This question already has answers here:
INT comparison without WHERE statement
(4 answers)
Closed 9 years ago.
Thread moved to: INT comparison without WHERE statement
Minor point, you have at least three syntax errors in your query. There is the comma after Day 0, the lack of a date part in datediff(), and the double equal sign. As to what you are trying to accomplish, it a case construct might be the way to go.
select case
when datediff(day, date1, date2) = 0 then 'Day 0'
when abs(datediff(day, date1, date2)) = 1 then 'Day 1'
else 'something else' end WhatDay
from etc
You probably want a where clause so that you are not querying the entire table. Doing that is rarely necessary.
If you need multiple columns then you only have one realistic choice, a CASE statement, but that's messy. However, with a little joining we can make it cleaner. Let's assume the key for the table is Id, we might write a statement like this:
SELECT t.*,
CASE WHEN i.diff = 0 THEN 'Day 0' ELSE NULL END AS Day0,
CASE WHEN i.diff = 1 THEN 'Day 1' ELSE NULL END AS Day1,
CASE WHEN i.diff = 2 THEN 'Day 2' ELSE NULL END AS Day2,
CASE WHEN i.diff = 3 THEN 'Day 3' ELSE NULL END AS Day3,
CASE WHEN i.diff = 4 THEN 'Day 4' ELSE NULL END AS Day4,
CASE WHEN i.diff = 5 THEN 'Day 5' ELSE NULL END AS Day5,
FROM table t
JOIN (
SELECT Id, DATEDIFF(
STR_TO_DATE(date, '%Y-%m-%d %H:%i:%s'), b.datetwo
) AS diff
FROM table
) i ON i.Id = t.Id AND i.diff >= 0 AND i.diff <= 5
With this statement we now know what bucket each row falls into; if the value isn't NULL.
Related
I want to select the sum of T_No where Transactions are equal to R and subtract it by T_No where Transactions are equal to D and the answer of this should greater than zero for a CustomerID which would be a input (an int input declared in a stored procedure)
((Sum(T_No) where Transactions = R - Sum(T_No) where Transactions = D ) > 0) where CoustomerID = #input
Example : for ID = 1 it would be ((20+15) - 10) > 0
I Have tried so many things but either syntax is wrong, wrong value or it does not accept, and I am literally Stuck, this was my final attempt
SELECT
(select ( select Sum(T_No) where Transactions = R) - (select Sum(T_No) where Transactions = D) as C_T )
FROM CustomerTrans WHERE C_T > 0 ;
Conditional aggregation should help:
SELECT
SUM(CASE WHEN Transaction = 'R' THEN t_no ELSE 0 END) - SUM(CASE WHEN Transaction = 'D' THEN t_no ELSE 0 END)
FROM CustomerTrans
WHERE CoustomerID = #yourCustomerIdVariable
As you're writing a sproc you can assign the result of this to a variable and then decide what to do if the result is negative. (I would personally log an error for example, rather than just hide those results). If the result is null, then there were no transactions for that customer
ps; I used Transaction because that's what your screenshot showed, and I figured a screenshot is less likely to contain a typo than code with syntax errors. Adjust if required
you where kinda close, I would sum like you, only the syntax is a bit off, you can't have aggregate fields in Where, thats why you should use having, also case when syntax is not correct.
Select
CoustomerID,
Sum(case when Transactions = 'R' then T_No else 0 end) -
Sum(case when Transactions = 'D' then T_No else 0 end) as C_T
FROM CustomerTrans
group by CoustomerID
having (Sum(case when Transactions = 'R' then T_No else 0 end) -
Sum(case when Transactions = 'D' then T_No else 0 end))>0
new to MySQL..so pls help me out with this basic code..
i have a query something like this...
select weekofyear(id_time),
(id),
#Tat1:=exp1,
#Tat2:=exp2,
#check1:=exp3,
#check2:=exp4,
(case when #check2=0 then
(case when (#Tat1>(#Tat2+30) or (#check1=1 and (#Tat1>#Tat2+10))) then 1 else 0 end)
else
(case when (#Tat1>(#Tat2+30) or (#check1=1 and (#Tat1>#Tat2+20))) then 1 else 0 end)
end) as BO
from datb
where cid=18
and id_time between '2019-11-01 06:00:00' and '2019-11-25 06:00:00'
and it gives correct results as--here
however i want to use sum after case when statement so that I can get total values where BO=1 and group by week of year , so i made following changes-
select weekofyear(id_time),
count(id),
#Tat1:=exp1,
#Tat2:=exp2,
#check1:=exp3,
#check2:=exp4,
sum(case when #check2=0 then
(case when (#Tat1>(#Tat2+30) or (#check1=1 and (#Tat1>#Tat2+10))) then 1 else 0 end)
else
(case when (#Tat1>(#Tat2+30) or (#check1=1 and (#Tat1>#Tat2+20))) then 1 else 0 end)
end) as BO
from datb
where cid=18
and id_time between '2019-11-01 06:00:00' and '2019-11-25 06:00:00'
group by weekofyear(id_time)
but it always returns 0 as output.
Output --here 2
Please help , I don't know what am I doing wrong here.
Thanx !
As others have already said, session variables can be unpredictable (especially when aggregation gets mixed in). That said, it doesn't look like you're using the session variables to carry over values from one row to the next (as is often done), but to just make aliases of sorts for calculations you don't want to repeat.
A better way to handle that is just through subqueries.
SELECT woy, id, Tat1, Tat2, check1, check2
, CASE
WHEN check2=0 THEN (
CASE
WHEN (Tat1>(Tat2+30) OR (check1=1 AND (Tat1>Tat2+10))) THEN 1
ELSE 0
END
)
ELSE (
CASE WHEN (Tat1>(Tat2+30) OR (check1=1 AND (Tat1>Tat2+20))) THEN 1
ELSE 0
END
)
END AS BO
FROM (
SELECT WEEKOFYEAR(id_time) AS woy
, id
, exp1 AS Tat1
, exp2 AS Tat2
, exp3 AS check1
, exp4 AS check2
FROM datb
WHERE cid=18
AND id_time BETWEEN '2019-11-01 06:00:00' AND '2019-11-25 06:00:00'
) AS subQ
;
You can then tweak the above query for aggregation, or use it as a subquery for an aggregating outer query.
select x,
count(case when i='abc' then 1 else null end) as ele1,
count(case when i='def' then 1 else null end) as ele2,
sum(ele1+ele2) as sum1 from (INNER QUERY)
When i am using sum(ele1+ele2), it is throwing error that ele1 not found. How to fetch sum1 in the same query without using any other outer query?
You can't use alias as column name in select
select x,
count(case when i='abc' then 1 else null end) as ele1,
count(case when i='def' then 1 else null end) as ele2,
sum( ( case when i='abc' then 1 else null end ) +
( case when i='def' then 1 else null end ) ) as sum1
from (INNER QUERY)
You cannot use alias as a column name, but if your concern is in verboseness - in your particular case you can write something like below, which is easy readable and skinny enough (for BigQuery Legacy SQL)
SELECT
SUM( i ='abc' ) AS ele1,
SUM( i = 'def' ) AS ele2,
SUM( i IN ('abc', 'def') ) AS sum1
FROM (INNER QUERY)
I have a column 'hour'
I have a column 'kind' (it can be 1,2 or 3)
I'd like to do something like:
SELECT count(id), SUM(hour) as totHour, SUM( IF ( kind = 1, 1, 0 ) ) as countKindOne
or
SELECT count(id), SUM(hour) as totHour, COUNT( IF ( kind = 1 ) ) as countKindOne
But mysql tell me I've an error... what's the error!?
Please see this stackoverflow topic: MySQL SUM IF field b = field a
.. I'm not able to reply this ...
You can use a CASE statement:
SELECT count(id),
SUM(hour) as totHour,
SUM(case when kind = 1 then 1 else 0 end) as countKindOne
you want something like:
SELECT count(id), SUM(hour) as totHour, SUM(kind=1) as countKindOne;
Note that your second example was close, but the IF() function always takes three arguments, so it would have had to be COUNT(IF(kind=1,1,NULL)). I prefer the SUM() syntax shown above because it's concise.
You can also use SUM + IF which is shorter than SUM + CASE:
SELECT
count(id)
, SUM(IF(kind=1, 1, 0)) AS countKindOne
, SUM(CASE WHEN kind=2 THEN 1 ELSE 0 END) AS countKindTwo
There is a slight difference between the top answers, namely SUM(case when kind = 1 then 1 else 0 end) and SUM(kind=1).
When all values in column kind happen to be NULL, the result of SUM(case when kind = 1 then 1 else 0 end) is 0, whereas the result of SUM(kind=1) is NULL.
An example (http://sqlfiddle.com/#!9/b23807/2):
Schema:
CREATE TABLE Table1
(`first_col` int, `second_col` int)
;
INSERT INTO Table1
(`first_col`, `second_col`)
VALUES
(1, NULL),
(1, NULL),
(NULL, NULL)
;
Query results:
SELECT SUM(first_col=1) FROM Table1;
-- Result: 2
SELECT SUM(first_col=2) FROM Table1;
-- Result: 0
SELECT SUM(second_col=1) FROM Table1;
-- Result: NULL
SELECT SUM(CASE WHEN second_col=1 THEN 1 ELSE 0 END) FROM Table1;
-- Result: 0
From MYSQL I solved the problem like this:
SUM(CASE WHEN used = 1 THEN 1 ELSE 0 END) as amount_one,
Hope this helps :D
It is worth noting that you can build upon Gavin Toweys answer by using multiple fields from across your query such as
SUM(table.field = 1 AND table2.field = 2)
You can also use this syntax for COUNT and I am sure other functions as well.
I have a table of reports that include the fields Case (unique number), ISR (Individual Safety Report - unique number) and YearsOld.
There can be more than one ISR for each Case. I want to count the number of unique Cases within age groups.
This SQL gives me a count of the number of ISRs:
SELECT
COUNT(CASE WHEN `YearsOld` = -2) THEN 1 END) `No Report`,
COUNT(CASE WHEN `YearsOld` BETWEEN 0 AND 5) THEN 1 END) `0 to 5`
COUNT(CASE WHEN `YearsOld` BETWEEN 6 AND 12) THEN 1 END) `6 to 12`
FROM `Demographics`
is there a way to modify this to count the DISTINCT Cases for these Age Groups?
If your "case" variable is unique, you can certainly put the distinct keyword in the SQL CASE syntax directly:
Count(distinct CASE when yearsold between 6 and 12 then case else null end)
That way, each unique value of the case variable is counted only once.
Just a note on column naming, I would suggest not using a word that has meaning in SQL if you have a choice (I.e. use 'case_num' instead of case).
You could use a subquery to filter your demographics table for a single YearsOld field per case, although if that case might have been related to difference ages for different ISR it'll only end up being counted in one bracket (perhaps this is what you want?):
SELECT
... -- as you currently have
FROM (
SELECT `Case`, `YearsOld` from `Demographics` GROUP BY `Case`
) t;
Alternatively, to "count" each "distinct" "case" within each bracket, you do literally that:
SELECT
COUNT(DISTINCT CASE WHEN `YearsOld` = -2 THEN 1 END) `No Report`,
COUNT(DISTINCT CASE WHEN `YearsOld` BETWEEN 0 AND 5 THEN `Case` END) `0 to 5`,
COUNT(DISTINCT CASE WHEN `YearsOld` BETWEEN 6 AND 12 THEN `Case` END) `6 to 12`
FROM Demographics;