PostgreSQL CASE 条件表达式

本文介绍如何使用 PostgreSQL CASE 条件表达式实现逻辑处理。

PostgreSQL CASE 表达式是一个条件表达式,它与其他编程语言中的 if-else 语句作用相同。

您可以在 SELECT 语句以及 WHERE, GROUP BY, 和 HAVING 子句中使用 CASE 表达式。

PostgreSQL CASE 语法

这里是 PostgreSQL CASE 表达式的语法:

CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ELSE value3
END

解释:

  • condition1, condition2 是一些布尔表达式,返回值为 truefalse
  • 这个表达式可以理解为:如果 condition1 为真返回 result1,如果 condition2 为真返回 result2,否则返回 result3
  • 您可以指定一个或者多个 WHEN ... THEN 判断。
  • ELSE 部分是可以省略的,您只能指定一个 ELSE 语句。
  • 所有的判断从上向下依次判断,直到遇到条件为真,并返回此条件对应的值。如果没有条件为真,则返回 ELSE 指定的值。如果没有指定 ELSE,则返回 NULL

如果所有的条件都是针对同一个字段或者表达式进行等值判断,则可以将 CASE 表达式简写为如下形式:

CASE expr
    WHEN value1 THEN result1
    WHEN value2 THEN result2
    ELSE result3
END

这个表达式的含义是:如果 expr 等于 value1,则返回 result1,如果 expr 等于 value2,则返回 result2,否则返回 result3

PostgreSQL CASE 实例

简单示例

先看一个简单的示例。

比如,您想要获取当前日期是星期几的名称:

SELECT
  current_date "Today",
  CASE
    WHEN extract(DOW FROM current_date) = 1 THEN 'Monday'
    WHEN extract(DOW FROM current_date) = 2 THEN 'Tuesday'
    WHEN extract(DOW FROM current_date) = 3 THEN 'Wednesday'
    WHEN extract(DOW FROM current_date) = 4 THEN 'Thursday'
    WHEN extract(DOW FROM current_date) = 5 THEN 'Friday'
    WHEN extract(DOW FROM current_date) = 6 THEN 'Saturday'
    ELSE 'Sunday'
  END "Day of Week";
   Today    | Day of Week
------------+-------------
 2022-09-19 | Monday

这里,我们使用 current_date 获得当前的日期,并使用 extract() 函数获取当前日期的工作日编号。

由于上面的 CASE 表达式中的条件都是等值判断,因此我们可以将 CASE 表达式简化为:

SELECT
  current_date "Today",
  CASE extract(DOW FROM current_date)
    WHEN 1 THEN 'Monday'
    WHEN 2 THEN 'Tuesday'
    WHEN 3 THEN 'Wednesday'
    WHEN 4 THEN 'Thursday'
    WHEN 5 THEN 'Friday'
    WHEN 6 THEN 'Saturday'
    ELSE 'Sunday'
  END "Day of Week";
   Today    | Day of Week
------------+-------------
 2022-09-19 | Monday

使用 CASE 表达式实现自定义排序

有时候单纯的按照字段的值排序并不能满足要求,我们需要按照自定义的顺序的排序。比如,我们需要按照电影分级 'G', 'PG', 'PG-13', 'R', 'NC-17' 的顺序对影片进行排序。

对于这样的需求,它可以理解为按照列表中元素的索引位置进行排序。我们使用 CASE 子句函数实现它。

在以下实例中,我们使用 Sakila 示例数据库中的 film作为演示。

假设您要根据影片的分级按照的 'G', 'PG', 'PG-13', 'R', 'NC-17' 顺序对影片进行排序。 下面使用 CASE 表达式实现自定义排序:

SELECT
    film_id, title, rating
FROM
    film
ORDER BY CASE rating
    WHEN 'G' THEN 1
    WHEN 'PG' THEN 2
    WHEN 'PG-13' THEN 3
    WHEN 'R' THEN 4
    WHEN 'NC-17' THEN 5
END;

     357 | GILBERT PELICAN             | G
     597 | MOONWALKER FOOL             | G
     354 | GHOST GROUNDHOG             | G
...
     595 | MOON BUNCH                  | PG
       6 | AGENT TRUMAN                | PG
     600 | MOTIONS DETAILS             | PG
...
       9 | ALABAMA DEVIL               | PG-13
     657 | PARADISE SABRINA            | PG-13
     956 | WANDA CHAMBER               | PG-13
...
     749 | RULES HUMAN                 | R
       8 | AIRPORT POLLOCK             | R
      17 | ALONE TRIP                  | R
...
     520 | LICENSE WEEKEND             | NC-17
     517 | LESSON CLEOPATRA            | NC-17
     114 | CAMELOT VACATION            | NC-17
...
(1000 rows)

在这个例子中,我们使用 CASE 子句将电影的分级转换为一个数字。然后使用 ORDER BY 按照这个数字进行排序。

结论

在本文中,我们讨论了 PostgreSQL CASE 条件表达式的语法,并提供了几个示例。