PostgreSQL 教程: CASE 表达式

八月 29, 2023

摘要:在本教程中,您将学习如何使用 PostgreSQL 的 CASE 条件表达式来生成条件查询。

PostgreSQL 的CASE表达式与其他编程语言中的IF/ELSE语句相同。它允许您向查询添加 if-else 逻辑以形成强大的查询。

由于CASE是一个表达式,因此您可以在任何可以使用表达式的地方使用它,例如SELECTWHEREGROUP BYHAVING子句。

CASE表达式有两种形式:通用形式和简单形式。

1) 通用 CASE 表达式

下面说明了CASE语句的一般形式:

CASE 
    WHEN condition_1  THEN result_1
    WHEN condition_2  THEN result_2
    [WHEN ...]
    [ELSE else_result]
END

在此语法中,每个条件 (condition_1, condition_2…) 都是一个返回truefalse的布尔表达式。

当条件计算结果为false时,CASE表达式从上到下计算下一个条件,直到找到计算结果为true的条件。

如果一个条件的计算结果为true,则CASE表达式返回条件后的相应结果。例如,如果condition_2的计算结果为true,则CASE表达式返回result_2。并且,它会立即停止计算下一个表达式。

如果所有条件的计算结果均为false,则CASE表达式返回ELSE关键字后面的结果 (else_result) 。如果省略ELSE子句,则CASE表达式返回NULL

让我们看一下示例数据库中的film表。

img

A) 通用 CASE 表达式示例

假设您想根据以下逻辑按长度标记电影:

  • 如果长度少于 50 分钟,则影片很短。
  • 如果长度大于 50 分钟且小等于120分钟,则该影片为中等影片。
  • 如果长度大于 120 分钟,则影片较长。

要应用此逻辑,您可以在SELECT语句中使用CASE表达式,如下所示:

SELECT title,
       length,
       CASE
           WHEN length> 0
                AND length <= 50 THEN 'Short'
           WHEN length > 50
                AND length <= 120 THEN 'Medium'
           WHEN length> 120 THEN 'Long'
       END duration
FROM film
ORDER BY title;

输出:

img

请注意,我们在CASE表达式后面放置了一个列别名 duration

B) 配合聚合函数使用通用 CASE 表达式的示例

假设您要使用以下逻辑为电影分配价格段:

  • 如果租金率为 0.99,则该片是经济的。
  • 如果租金率为 1.99,则该片是大众化的。
  • 如果租金是 4.99,这部电影就很溢价了。

您想知道属于经济型、大众型和高级型的电影数量。

在这种情况下,您可以使用CASE表达式来构造查询,如下所示:

SELECT
	SUM (CASE
               WHEN rental_rate = 0.99 THEN 1
	       ELSE 0
	      END
	) AS "Economy",
	SUM (
		CASE
		WHEN rental_rate = 2.99 THEN 1
		ELSE 0
		END
	) AS "Mass",
	SUM (
		CASE
		WHEN rental_rate = 4.99 THEN 1
		ELSE 0
		END
	) AS "Premium"
FROM
	film;

查询结果如下:

img

在此示例中,如果租金属于每个价格段,我们使用CASE表达式返回 1 或 0。我们应用SUM函数来计算每个价格段的电影总数。

2) 简单 CASE 表达式

PostgreSQL 提供了另一种形式的CASE表达式,称为简单形式,如下所示:

CASE expression
   WHEN value_1 THEN result_1
   WHEN value_2 THEN result_2 
   [WHEN ...]
   [ELSE else_result]
END

CASE首先计算expression,并将结果值与WHEN子句中的每个值(value_1, value_2, …)顺序进行比较,直到找到匹配项。

一旦expression的结果值等于WHEN子句中的某个值(value1、value2 等),则CASE返回THEN子句中相应的表达式结果值。

如果CASE未找到任何匹配项,则返回ELSE后面的else_result,或者如果省略了ELSE子句则返回NULL值。

A) 简单 CASE 表达式示例

以下语句使用CASE表达式将评级描述添加到输出中:

SELECT title,
       rating,
       CASE rating
           WHEN 'G' THEN 'General Audiences'
           WHEN 'PG' THEN 'Parental Guidance Suggested'
           WHEN 'PG-13' THEN 'Parents Strongly Cautioned'
           WHEN 'R' THEN 'Restricted'
           WHEN 'NC-17' THEN 'Adults Only'
       END rating_description
FROM film
ORDER BY title;

img

在此示例中,我们使用一个简单的CASE表达式将film表中的评级与一些文字值(如 G、PG、NC17、PG-13)进行比较,并返回相应的评级描述。

B) 配合聚合函数使用简单 CASE 表达式的示例

以下语句使用带有SUM函数的CASE表达式来计算每个评级中的电影数量:

SELECT
       SUM(CASE rating
             WHEN 'G' THEN 1 
		     ELSE 0 
		   END) "General Audiences",
       SUM(CASE rating
             WHEN 'PG' THEN 1 
		     ELSE 0 
		   END) "Parental Guidance Suggested",
       SUM(CASE rating
             WHEN 'PG-13' THEN 1 
		     ELSE 0 
		   END) "Parents Strongly Cautioned",
       SUM(CASE rating
             WHEN 'R' THEN 1 
		     ELSE 0 
		   END) "Restricted",
       SUM(CASE rating
             WHEN 'NC-17' THEN 1 
		     ELSE 0 
		   END) "Adults Only"
FROM film;

img

在本教程中,您学习了如何使用 PostgreSQL 的CASE表达式来生成复杂的查询。