Reputation: 2082
I am trying to revise my SQL concepts, and while doing so, I faced a curious case which I was not able to understand. Below is my schema and data:
CREATE TABLE Customer
(
name varchar(255),
city varchar(255),
country varchar(255),
id int
);
INSERT INTO customer VALUES ("ram923", null, "aIndia3",1);
INSERT INTO customer VALUES ("ram92", null, "dIndia3",1);
INSERT INTO customer VALUES ("ram83", null, "dIndia4",1);
INSERT INTO customer VALUES ("ram94", null, "dIndia4",1);
INSERT INTO customer VALUES ("ram", "city1", "bIndia1",1);
INSERT INTO customer VALUES ("ram1", "city2", "aIndia1",1);
INSERT INTO customer VALUES ("ram2", "city3", "aIndia1",1);
INSERT INTO customer VALUES ("ram3", "city4", "bIndia2",1);
INSERT INTO customer VALUES ("ram4", "city5", "bIndia2",1);
INSERT INTO customer VALUES ("ram8", null, "bIndia2",1);
INSERT INTO customer VALUES ("ram9", null, "bIndia2",1);
INSERT INTO customer VALUES ("ram5", "city6", "cIndia3",1);
INSERT INTO customer VALUES ("ram6", "city7", "dIndia4",1);
INSERT INTO customer VALUES ("ram67", "city71", "dIndia3",1);
INSERT INTO customer VALUES ("ram622", null, "eIndia3",1);
INSERT INTO customer VALUES ("ram81", null, "cIndia3",1);
Then I execute this select query which would use CASE
statement with ORDER BY
to order the customers by City. However, if City is NULL, then order by Country:
SELECT
name, City, Country
FROM
Customer
ORDER BY
(CASE
WHEN City IS NULL THEN Country
ELSE City
END);
The output I get is not quite the way I thought it would be:
name City Country
------------------------
ram923 (null) aIndia3
ram8 (null) bIndia2
ram9 (null) bIndia2
ram81 (null) cIndia3
ram city1 bIndia1
ram1 city2 aIndia1
ram2 city3 aIndia1
ram3 city4 bIndia2
ram4 city5 bIndia2
ram5 city6 cIndia3
ram6 city7 dIndia4
ram67 city71 dIndia3
ram92 (null) dIndia3
ram83 (null) dIndia4
ram94 (null) dIndia4
ram622 (null) eIndia3
Can anyone explain how the CASE
with ORDER BY
is working here? Why it would not put all null
cities together and then do ORDER BY
country?
Upvotes: 0
Views: 203
Reputation: 35603
The easiest way understand how a case expression affects your order by
clause is to output the same case expression as part of the select
clause
SELECT
name , City , Country
,(
CASE
WHEN City IS NULL
THEN Country
ELSE City
END
) AS sort_by_case
FROM Customer
ORDER BY
CASE
WHEN City IS NULL
THEN Country
ELSE City
END
;
or:
SELECT
name , City , Country
,(
CASE
WHEN City IS NULL
THEN Country
ELSE City
END
) AS sort_by_case
FROM Customer
ORDER BY
sort_by_case
;
Upvotes: 0
Reputation: 42728
Can anyone explain how the CASE with ORDER BY is working here?
Simply add the expression used in ORDER BY, to output list:
SELECT name, City, Country , CASE WHEN City IS NULL THEN Country ELSE City END expression_from_order_by FROM customer ORDER BY (CASE WHEN City IS NULL THEN Country ELSE City END);
name | City | Country | expression_from_order_by |
---|---|---|---|
ram923 | null | aIndia3 | aIndia3 |
ram8 | null | bIndia2 | bIndia2 |
ram9 | null | bIndia2 | bIndia2 |
ram81 | null | cIndia3 | cIndia3 |
ram | city1 | bIndia1 | city1 |
ram1 | city2 | aIndia1 | city2 |
ram2 | city3 | aIndia1 | city3 |
ram3 | city4 | bIndia2 | city4 |
ram4 | city5 | bIndia2 | city5 |
ram5 | city6 | cIndia3 | city6 |
ram6 | city7 | dIndia4 | city7 |
ram67 | city71 | dIndia3 | city71 |
ram92 | null | dIndia3 | dIndia3 |
ram83 | null | dIndia4 | dIndia4 |
ram94 | null | dIndia4 | dIndia4 |
ram622 | null | eIndia3 | eIndia3 |
db<>fiddle here
Now it is absolutely clear how does it works.
Upvotes: 2
Reputation: 1270463
What is hard to understand? You can see the sorting key by replacing the expression, although I would simplify it as:
select c.*, coalesce(city, country)
from customers c
order by coalesce(city, country);
In your sample data, all the country
values are before the city
values alphabetically.
Upvotes: 1