I have three columns: identifier, driver_id, driver_id_was
My condition is to eliminate those identifiers which always had driver_id and driver_ids_was as -1.
But my current query is doing the opposite.It is including all identifiers which has driver_id and driver_id_was as -1 at least once.
SELECT identifier
,model
,sw_pkg_version
,COUNT(CASE WHEN driver_id_was != -1 THEN 1 ELSE NULL END) AS "count_driver_id_was_not"
,COUNT(CASE WHEN driver_id_was = -1 THEN 1 ELSE NULL END) AS "count_driver_id_was"
,COUNT(CA
FROM eld_messages
WHERE model LIKE '%ca'
AND created_at > getdate()-30
GROUP BY identifier
,driver_id_was
,model
,sw_pkg_version
,driver_id
HAVING count_driver_id_was_not = 0
AND count_driver_id_was > 0;
My condition is to eliminate those identifiers which always had driver_id and driver_ids_was as -1.
Is this what you want?
select identifier
from eld_messages
group by identifier
having sum(case when count_driver_id_was_not <> -1 then 1 else 0 end) > 0 or
sum(case when count_driver_id_was <> -1 then 1 else 0 end) > 0;
Or, similarly but more succinctly:
select distinct identifier
from eld_messages
where count_driver_id_was_not <> -1 or count_driver_id_was <> -1
This is how I understand the question but it’s hard to be sure without sample data or further clarification. Maybe this answer will generate some response.
SELECT identifier
,model
,sw_pkg_version
FROM eld_messages
WHERE model LIKE '%ca'
AND created_at > getdate()-30
AND driver_id <> -1
AND driver_id_was <> -1
Related
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.
In this code its able to alias each case statement separately like,
SELECT
id,
SUM(CASE
WHEN (a.place = 'CHN' AND a.salary = 20000)
THEN '1'
ELSE '0'
END) AS '20K Salary',
SUM(CASE
WHEN (a.place = 'CHN' and a.salary = 35000)
THEN '1'
ELSE '0'
END) AS '35K Salary'
FROM Employee a;
but when nested CASE statement is used,
SELECT
id,
SUM(CASE
WHEN (a.place = 'CHN')
THEN (CASE
WHEN a.salary = 20000
THEN '1'
ELSE '0'
END) AS '20K Salary',
(CASE
WHEN a.salary = 35000
THEN '1'
ELSE '0'
END) AS '35K Salary'
END)
FROM Employee a;
its not possible to execute the query
In the first set of code each case statement is part of the SELECT list (i.e. they are in a comma separated list following SELECT) so each returns a column. In the second set of code there is only one case statement in the SELECT list, the fact that it is nested has no impact on this. Also the syntax for the nested case isn't correct because the THEN part is followed by two expressions separated by commas which is not allowed.
Of course this is possible to do what you want. You want to create two columns, so each needs its own logic and its own alias:
SELECT id,
SUM(CASE WHEN a.place = 'CHN' AND a.salary = 20000 THEN 1 ELSE 0
END) as Salary_20K,
SUM(CASE WHEN a.place = 'CHN' AND a.salary = 35000 THEN 1 ELSE 0
END) as Salary_35K
FROM Employee a;
Note: Don't put numeric constants in single quotes. Only use single quotes for string and date constants.
I am wondering how to fix this query.
SELECT
SUM(`month_using`) used,
SUM(`month_cash`) paycash,
SUM(`month_profit` CASE WHEN `id` <> 'system' THEN 1 ELSE 0 END) profit
FROM `_using_month`
WHERE MONTH(`month_date`) = {month} AND YEAR(`month_date`) = {year}
Thanks
Use Group by clause to get multiple SUM:
For Example:
SELECT YEAR(month_date), MONTH(month_date),
SUM(month_using) used, SUM(month_cash) paycash,
SUM(month_profit CASE WHEN id <> 'system' THEN 1 ELSE 0 END) profit
FROM _using_month
GROUP BY YEAR(month_date), MONTH(month_date)
Have this query:
SELECT
count(*) as Total,
SUM(CASE WHEN gender = 1 then 1 ELSE 0 END) Male,
SUM(CASE WHEN gender = 2 then 1 ELSE 0 END) Female,
SUM(CASE WHEN gender = 0 then 1 ELSE 0 END) Unknown,
CASE
WHEN age>2 AND age<15 THEN '2-15'
WHEN age>18 AND age<25 THEN '18-25'
END AS var
FROM
persons
WHERE
1=1
AND `date` > '2012-01-10'
AND `date` < '2013-01-07'
GROUP BY
CASE
WHEN age>2 AND age<15 THEN '2-15'
WHEN age>18 AND age<25 THEN '18-25'
END
And is resulting this:
Total Male Female Unknown var
29 17 12 0 NULL
7 0 7 0 18-25
3 0 3 0 2-15
1st question: Why is this resulting that NULL ? What could be done to only show results with values?
2nd question: mysql is ordering my var column with 18-25 before 2-15, migth be because of number 1 cames first then number 2. But the point is order that as numbers, and 2 came first then 18.
Cheers :)
1st answer:
It is NULL because it does not satisfy any of your CASE conditions for the age. Adding a clause to the WHERE like this should do it:
WHERE (age > 2 AND age < 15) OR (age > 18 AND age < 25)
2nd answer:
You are correct, it is ordering them by strings (because that is what they are). Just change the direction of the sort by doing ORDER ASC or ORDER DESC
This is because all CASE expression has an (implied, default) ELSE NULL part. SO, any age value that is not caught by either the age>2 AND age<15or the age>18 AND age<25 condition, results in the NULL value being grouped.
Solution is to add one more restriction at the WHERE clause:
WHERE 1=1
AND `date` > '2012-01-10' AND `date` < '2013-01-07'
AND ( (age>2 AND age<15) OR (age>18 AND age<25) ) -- this
For the second question, you can use a function on age to avoid the comparison being made on the var (which is a string):
ORDER BY MIN(age)
or just:
ORDER BY age
None of the above is by the SQL standard but it works in MySQL, under the default non-ANSI settings. If you want to be 100% by the book, you can change slightly the var:
SELECT count(*) as Total,
SUM(CASE WHEN gender = 1 then 1 ELSE 0 END) Male,
SUM(CASE WHEN gender = 2 then 1 ELSE 0 END) Female,
SUM(CASE WHEN gender = 0 then 1 ELSE 0 END) Unknown,
CASE
WHEN age>2 AND age<15 THEN '02-15' -- this was changed
WHEN age>18 AND age<25 THEN '18-25'
END AS var
FROM persons
WHERE 1=1
AND `date` > '2012-01-10' AND `date` < '2013-01-07'
AND ( (age>2 AND age<15) OR (age>18 AND age<25) )
GROUP BY
CASE
WHEN age>2 AND age<15 THEN '02-15'
WHEN age>18 AND age<25 THEN '18-25'
END
ORDER BY var ;
you are getting NULL
because it doesnt meet your CASE
CASE
WHEN age>2 AND age<15 THEN '2-15' // U HAVE BETWEEN 2-15
WHEN age>18 AND age<25 THEN '18-25' // u have between 18-25
// but u dont have between 15-18
//and u get null because your value is between 15-18
so try to add other case in that range.
second question because they are strings , not numbers.
try order them by age
I am using a MySQL database and I have a big mysql_query that works completely fine except for this one line.
SELECT game_id,
COALESCE(
SUM(CASE WHEN game_score = 1 THEN 1 ELSE 0 END)
-
SUM(CASE WHEN game_score = 0 THEN 1 ELSE 0 END), 0) AS score
FROM ....
WHERE ....
GROUP BY ....
This line returns me almost all of the numbers that I want, yet they are the same numbers as when I wasn't using the COALESCE function.
I would like this statement to return me 0 when there is a game_id that has an emptygame_score` field.
Where is my code going wrong?
you can also use decode function like this ---
SELECT game_id,
SUM(DECODE(game_score, null, 0, 0, -1, 1, 0)) AS score
FROM ....
WHERE ....
GROUP BY ....
I have checked this query for working, its fine
hope it helps you....
add
when game_score is null then ...
Edit
SELECT game_id, case when game_score is null then 0 else
SUM(CASE WHEN game_score = 1 THEN 1 ELSE 0 END)
-
SUM(CASE WHEN game_score = 0 THEN 1 ELSE 0 END) end AS score
FROM games
group by ...
See this SQLFiddle Example
Use is null like
CASE WHEN game_score = 1 THEN 1
when game_score is null THEN 0
ELSE 0 END
The problem is that game_id can have an empty game_score field in one row and a valid one in another. Your code picks up the valid one and returns non-null.
Fix this problem by looking for this case explicitly, as the first argument to coalesce:
SELECT game_id,
(CASE WHEN count(*) <> count(game_score) then NULL
ELSE COALESCE(SUM(CASE WHEN game_score = 1 THEN 1 ELSE 0 END),
. . .
I'm not sure what the coalesce is trying to do. It seems to be adding one for a bunch of different game_scores. Can you use one of the following instead:
COUNT(game_score) ?
SUM(case when game_score between 1 and xx then 1 else 0 end) ?
Use the COALESCE function around your field name in your statements instead of surrounding the SUM function:
SUM(CASE COALESCE(game_score,0) WHEN 1 THEN 1 ELSE 0 END) - SUM(CASE COALESCE(game_score,0) WHEN 0 THEN 1 ELSE 0 END)