I'm trying to mess around with putting CASE
statement in the ORDER BY
clause using a DISTINCT
in the SELECT
list, and finding some odd behavior that I don't understand. Here is some code:
select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU
from LoanerHeader order by
CASE WHEN 'a' = 'b' then Requester
when 'b' = 'c' then BU
else ISO_ID
end
This works. But if I change the 4th line to when 'b' = 'b' then BU
:
select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU
from LoanerHeader order by
CASE WHEN 'a' = 'b' then Requester
when 'b' = 'b' then BU
else ISO_ID
end
it breaks with error:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
When BU
is obviously in the select list. Even stranger is when I change the code to:
select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU
from LoanerHeader order by
CASE WHEN 'a' = 'b' then Requester
when 'b' = 'b' then BU
else BU --change is here
end
It works again! How does that even make sense? Can someone help me wrap my brain around this one?
Nope! Although it is most often used there, CASE is not limited to SELECT statements. For example, you can use it in clauses like IN , WHERE , HAVING , and ORDER BY .
How to use CASE with ORDER BY clause in SQL Server? To do this, we use the CASE after ORDER BY and then checks for column value. In above case, all records having Active = 1 is sorted on “Active ASC” order. All records having Active = 0 is sorted on 'LastName DESC' else 'FirstName DESC' order.
in php u can do it like : <? php $my_array = array (3,6,1,8,9) ; $sql = 'SELECT * FROM table WHERE id IN (3,6,1,8,9)'; $sql . = "\nORDER BY CASE id\n"; foreach($my_array as $k => $v){ $sql .
No, you can't pick a table to query using a CASE statement. CASE statements only go within expressions, such as for a column's value or as part of your WHERE expression.
The rules for CASE
are that the result should be cast to the datatype of the branch with highest precedence.
For the first query it uses contradiction detection and just generates a plan that sorts by ISO_ID
directly. This is numeric already so no need to implicitly cast and so matches the expression in the select list with no problem.
For the second query it can again determine at compile time that it needs to ORDER BY BU
. Except it actually needs to ORDER BY CAST(BU AS NUMERIC)
due to the above. This means it would need to ORDER BY
a computed expression not matching anything anything in the SELECT
list. Hence the problem.
Your third query removes the expression of higher precedence from the CASE
thus removing the need for an implicit cast (and hence the need to order by a computed expression).
As the computed expression is entirely dependant upon the columns in the SELECT DISTINCT
list however you could rewrite the second query as follows.
;WITH CTE AS
(
SELECT DISTINCT Requester,
ISO_ID AS ISO,
( ISO_ID - 5 + 50 ) AS 'someNum',
BU
FROM LoanerHeader
)
SELECT *
FROM CTE
ORDER BY CASE
WHEN 'a' = 'b' THEN Requester
WHEN 'b' = 'b' THEN BU
ELSE ISO
END
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With