在 SQL 中使用 ORDER BY 理解 CASE

Understanding of CASE with ORDER BY in SQL

我正在尝试修改我的 SQL 概念,而在这样做的同时,我遇到了一个我无法理解的奇怪案例。以下是我的架构和数据:

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);

然后我执行此 select 查询,该查询将使用 CASE 语句和 ORDER BY 按城市对客户进行排序。但是,如果 City 为 NULL,则按 Country 排序:

SELECT 
    name, City, Country
FROM
    Customer
ORDER BY
    (CASE
        WHEN City IS NULL THEN Country
        ELSE City
     END);
   

我得到的输出与我想象的不太一样:

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

谁能解释一下 CASEORDER BY 在这里是如何工作的?为什么不把所有 null 个城市放在一起然后做 ORDER BY 个国家?

有什么难理解的?您可以通过替换表达式来查看排序键,尽管我将其简化为:

select c.*, coalesce(city, country)
from customers c
order by coalesce(city, country);

在您的示例数据中,所有 country 值按字母顺序都在 city 值之前。

Can anyone explain how the CASE with ORDER BY is working here?

只需将 ORDER BY 中使用的表达式添加到输出列表:

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

现在完全清楚它是如何工作的了。

了解 case 表达式如何影响 order by 子句的最简单方法是输出相同的 case 表达式作为 select 子句的一部分

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
;

或:

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
;