How to make conditional ordering for two or more columns..I just tried the below code. is there any better way of writing this?
CASE WHEN d.receipt IS NULL AND c.receipt =1 then pr.account END ASC,
CASE WHEN d.receipt =1 AND c.receipt IS NULL then pr.account END ASC,
CASE WHEN d.receipt =1 AND c.receipt =0 then pr.account END ASC,
CASE WHEN d.receipt =1 AND c.receipt =1 then pr.account END ASC,
CASE WHEN d.receipt IS NULL AND c.receipt IS NULL THEN pr.amount END DESC,
CASE WHEN d.receipt IS NULL AND c.receipt =0 THEN pr.amount END DESC,
CASE WHEN d.receipt =0 AND c.receipt IS NULL THEN pr.amount END DESC,
CASE WHEN d.receipt =0 AND c.receipt =0 THEN pr.amount END DESC,
CASE WHEN d.receipt =0 AND c.receipt =1 THEN pr.amount END DESC
You could try this:
CASE WHEN d.receipt = 1 THEN pr.account
WHEN d.receipt = 0 THEN -pr.amount
WHEN c.receipt = 1 THEN pr.account
ELSE -pr.amount
END
It always sorts ascending but in some cases on the negative amount which of course results in descending.
The manual https://dev.mysql.com/doc/refman/5.7/en/case.html says:
"Each WHEN clause search_condition expression is evaluated until one is true, at which point its corresponding THEN clause statement_list executes. If no search_condition is equal, the ELSE clause statement_list executes, if there is one."
This implies that the expressions are evaluated in the order they are specified.
In other words, the 3rd condition (c.receipt = 1) is evaluated only if d.receipt is NULL.
Related
How to sort column and 0 come at last with case when?
Below is query:
SELECT iAdminID
, vFirstName
, vLastName
, iRank
FROM tbl_admin
WHERE eDeleted = 'No'
AND eStatus = 'Active'
ORDER
BY CASE WHEN iAdminID = 1
THEN 0
ELSE iRank=0 END
Below is result for above query:
But what I want is, first record should be as it is and others should
be according to iRank (1,2,3,4,5,6,7,8,0,0,0,0)
A simple method is to use severallevels of sorting.
You could do:
order by
case when iAdmin = 1 then 0 else 1 end,
case when iRank = 0 then 1 else 0 end,
iRank
In MySQL this can also be expressed as follows:
order by
(iAdmin = 1) desc,
iRank = 0,
iRank
A last option: if you know in advance the upper limit for iRank (say, no iRank will ever be greater than 1000), then you can skip one level:
order by
(iAdmin = 1) desc,
case when iRank = 0 then 1000 else iRank end
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
I need to write a MySQL statement, but not sure how to write it using case statements.
I would like to write something like this:
SELECT
*
FROM
table
WHERE:
IF sign_off_1 IS NOT NULL AND sign_off_1 IS NOT EQUAL TO 'Director'
sign_off_1_status MUST BE EQUAL TO Complete
IF sign_off_2 IS NOT NULL AND sign_off_2 IS NOT EQUAL TO 'Director'
sign_off_2_status MUST BE EQUAL TO Complete
IF sign_off_3 is IS NOT NULL AND sign_off_3 IS NOT EQUAL TO
'Director' sign_off_3_status MUST BE EQUAL TO Complete
Does anyone know the correct syntax to write this query?
It's not clear what you want to achieve. Does a row need to satisfy all three conditions, or just one of them? Either result can be achieved without using CASE expressions.
If the requirement is to use CASE expressions, and you need all three conditions to be true, you could do something like this:
SELECT t.id
FROM mytable t
WHERE CASE
WHEN t.sign_off_1 <> 'Director' AND t.sign_off_1_status = 'Complete'
THEN 1
ELSE 0
END
+ CASE
WHEN t.sign_off_2 <> 'Director' AND t.sign_off_2_status = 'Complete'
THEN 1
ELSE 0
END
+ CASE
WHEN t.sign_off_3 <> 'Director' AND t.sign_off_3_status = 'Complete'
THEN 1
ELSE 0
END
= 3
If you only need one of the conditions to be true, you could replace = 3 with > 0.
Note that an inequality comparison to a literal is sufficient to guarantee the column is not null. (If the column is NULL, the inequality comparison will return NULL, rather than TRUE.)
Again, the same result could be achieved without using CASE expressions.
You need to use OR and AND operator to simulate if condition in where clause. Try this.
SELECT *
FROM table
WHERE ( sign_off_1 <> 'Director'
AND sign_off_1_status = 'Complete' )
OR ( sign_off_2 <> 'Director'
AND sign_off_2_status = 'Complete' )
OR ( sign_off_3 <> 'Director'
AND sign_off_3_status = 'Complete' )
OR ( sign_off <> 'Director'
AND status <> 'Complete')
Update: am not completely sure about your comment. But this is what i understood.
WHERE (( sign_off_1 <> 'Director'
AND sign_off_1_status = 'Complete' )
OR ( sign_off_2 <> 'Director'
AND sign_off_2_status = 'Complete' )
OR ( sign_off_3 <> 'Director'
AND sign_off_3_status = 'Complete' ))
AND ( sign_off <> 'Director'
AND status <> 'Complete')
I have a query that returns value if the date range is match. and if it is not match it returns nothing.
SELECT start, end
FROM (`taxemployee`)
LEFT JOIN `project_staff_assignment` ON `project_staff_assignment`.`taxemployee_id` = `taxemployee`.`id`
WHERE (start >= '2014-09-01' AND end <= '2014-09-15')
OR (end >= '2014-09-15' AND start <= '2014-09-01')
GROUP BY `taxemployee`.`id`
ORDER BY `assigned_hours`ASC
if I put this on WHERE
OR coalesce(`start`, `end`) IS NULL
it returns null values, but not includes with value
How do I return result even if it is null and with value
here is sqlfiddle
http://sqlfiddle.com/#!2/8bbe4/3
UPDATE:
Refer fiddle here : http://sqlfiddle.com/#!2/2babf/2
I am using case statement to display the date if it falls in the range and am displaying null if not.
SELECT `taxemployee`.`id`, Nickname,
case when project_staff_assignment.startdt >= '2014-09-01' THEN project_staff_assignment.STARTdt ELSE NULL END AS STARTDATE,
case when project_staff_assignment.ENDdt >= '2014-09-15' THEN project_staff_assignment.ENDdt ELSE NULL END AS ENDDATE
FROM (`taxemployee`)
LEFT JOIN `project_staff_assignment` ON `project_staff_assignment`.`taxemployee_id` = `taxemployee`.`id`
GROUP BY `taxemployee`.`id`
ORDER BY `taxemployee`.`id` ASC
ORIGINAL ANSWER:
Refer Fiddle here: http://sqlfiddle.com/#!2/8bbe4/52
SELECT `taxemployee`.`id`, Nickname, start, end
FROM (`taxemployee`)
LEFT JOIN `project_staff_assignment` ON `project_staff_assignment`.`taxemployee_id` = `taxemployee`.`id`
WHERE (start >= '2014-08-01' AND end <= '2014-08-15')
OR (end >= '2014-08-15' AND start <= '2014-09-01')
OR coalesce(`start`, `end`) IS NULL
GROUP BY `taxemployee`.`id`
ORDER BY `taxemployee`.`id` ASC;
Records were not returned because,
Value was available only for 01.08.2014 whereas, your condition was for 01.09.2014
I have a query but I want to order the data as the following:
status (so I have the records with status = 1 on the top and status 2 at the bottom)
if the records have status = 1 then order them as the following
a) CASE WHEN i.assigned_to = '.USER_ID.' THEN 0 ELSE 1 END
b) CASE WHEN (i.approved_by > 0 OR i.approved_on IS NOT NULL) THEN 0 ELSE 1 END
c) i.priority DESC
d) i.created_on ASC
if the records have status = 2 then order the records by completed_on DESC
This is my current syntax but I can't figure out how to split the order
ORDER BY
i.status ASC,
CASE WHEN i.assigned_to = '.USER_ID.' THEN 0 ELSE 1 END,
CASE WHEN (i.approved_by > 0 OR i.approved_on IS NOT NULL) THEN 0 ELSE 1 END,
i.priority DESC,
i.created_on ASC
My query currently order all the records by
a) CASE WHEN i.assigned_to = '.USER_ID.' THEN 0 ELSE 1 END
b) (CASE WHEN (i.approved_by > 0 OR i.approved_on IS NOT NULL) THEN 0 ELSE 1 END)
c) i.priority DESC
d) i.created_on ASC
and I want it to order by those only if the status = 1 otherwise order by completed_on DESC
Try:
ORDER BY
i.status ASC,
CASE WHEN i.assigned_to = '.USER_ID.' and i.status = 1 THEN 0 ELSE 1 END,
CASE WHEN (i.approved_by > 0 OR i.approved_on IS NOT NULL) and i.status = 1
THEN 0 ELSE 1 END,
CASE WHEN i.status = 1 THEN i.priority END DESC,
CASE WHEN i.status = 1 THEN i.created_on END ASC,
CASE WHEN i.status = 2 THEN i.completed_on END DESC