PostgreSQL CASE 简介
下面是带有 WHEN-THEN 结构的 PostgreSQL CASE 的一般形式:
CASE
WHEN condition_1 THEN result_1
WHEN condition_2 THEN result_2
...
ELSE result_n
END
在 PostgreSQL 中构造 CASE 时,请牢记以下要点:
-
每个条件都是布尔表达式,依据其结果选择返回值。如果所有与
WHEN对应的表达式都评估为False,则显示ELSE部分对应的结果。若未指定ELSE部分,查询将返回 null。 -
条件通常应用于您所操作表中存在的一列。类似上述的条件查询结构通常与
SELECT语句一起使用。请注意:在指定布尔表达式的列(于CASE中)必须出现在查询的SELECT语句中。但当您将CASE与 where 子句配合使用时,则不受此限制(稍后详述)。 -
结果的数据类型必须一致。不能在
result_1返回string,而在result_2返回integer,等等。
下面通过一些示例来实践。
编写 PostgreSQL CASE
先从简单的开始。现在我们编写一个 CASE,按国家的独立年份进行分组。独立年份记录在 indep_year 列中。假设您需要遵循三个独立年份分组。我们将创建以下三组:
- 1900 年之前(
indep_year < 1900) - 1900 至 1930 年(含)(
indep_year <= 1930) - 1930 年之后(
indep_year > 1930)
查询的最终结果应包含以下列:
- name(国家名称)
- continent(所属洲)
- indep_year
- 以及您将创建的独立年份分组列。我们将其命名为
indep_year_group。
现在来编写查询:
SELECT name, continent, indep_year,
CASE WHEN indep_year < 1900 THEN 'before 1900'
WHEN indep_year <= 1930 THEN 'between 1900 and 1930'
ELSE 'after 1930' END
AS indep_year_group
FROM countries
ORDER BY indep_year_group;
(该查询灵感来自 DataCamp 的 Joining Data in SQL 课程。)
执行查询后,您会看到如巴勒斯坦、波多黎各等多个国家/地区在表中没有提供独立年份,因此被归入 between 1900 and 1930 分组。
PostgreSQL 的 CASE 可以包含多个条件。表中有少数记录的国家名与首都名相同。您可以把这一点加入前面的 CASE 中:
SELECT name, continent, indep_year,
CASE WHEN (indep_year < 1900) AND (countries.name = countries.capital) THEN 'before 1900 and capital same'
WHEN indep_year <= 1930 AND (countries.name = countries.capital) THEN 'between 1900 and 1930 and capital same'
ELSE 'after 1930_and_no_same_capital' END
AS indep_year_group
FROM countries
ORDER BY indep_year_group;
CASE 的另一个有趣之处在于它可以与 SUM() 等聚合函数配合使用。若要在聚合函数 SUM() 中使用 CASE,更适合换一张表来演示。我们创建一张名为 student_grades 的简单表,包含以下列及数据类型:
- student_name(字符串)
- student_stream(字符串)
- student_grade(字符)
使用以下查询创建该表:
CREATE TABLE student_grades
(student_name character varying,
student_stream character varying,
student_grade character);
现在往表中插入一些记录。您可以使用若干条 INSERT 语句。假设插入后,student_grades 表包含以下记录:

接下来,编写一个 CASE 来统计属于特定成绩分组的学生数量。如下所示,根据表中的记录存在 A、B、C 三个不同的成绩。条件查询应返回类似下图的输出:

对应查询如下:
SELECT
SUM (
CASE
WHEN student_grade = 'A' THEN
1
ELSE
0
END
) AS "High Scoring",
SUM (
CASE
WHEN student_grade = 'B' THEN
1
ELSE
0
END
) AS "Mid Scoring",
SUM (
CASE
WHEN student_grade = 'C' THEN
1
ELSE
0
END
) AS "Low Scoring"
FROM
student_grades;
这就是将 CASE 与聚合函数配合使用,从而挖掘数据有趣结论的方式。
结语与延伸阅读
本教程到此结束。您已学习如何将类似 if-then 的条件逻辑融入 SQL 查询,以产出有价值的报表。我们通过多个示例巩固了这一技能。若想挑战更高难度的练习,推荐学习以下 DataCamp 的 SQL 课程:
欢迎在评论区提出您对本教程的疑问。
条件表达式是任何编程范式中最基础的元素之一。常见的条件表达式包括
if-else代码块和switch分支。在 PostgreSQL 中,您可以使用与if-else十分类似的WHEN-THENCASE 来构造条件表达式。本文将带您逐步掌握。在编写条件查询之前,请先在本地搭建一个 PostgreSQL 数据库。您将在本教程的第一部分完成这一操作。
注意:为顺利跟进本教程,您需要具备 SQL 与 PostgreSQL 的基础知识。可参考以下资源进行复习:
在本地搭建 PostgreSQL 数据库
搭建数据库可参考这篇文章。成功恢复备份后,您应能在数据库中看到以下数据表:
不过,本教程只使用
countries表。您可自由探索备份中提供的其他表,或创建自己的数据库和数据表。如果您已恢复数据库备份,现在应当已有一个包含全球各国信息的数据表。下面我们简要浏览一下countries表。简要探索
countries表恢复数据库后,您可以在 PostgreSQL 默认安装附带的
pgAdmin界面中查看数据表。运行一条简单的SELECT语句,您即可了解表的列、数据类型以及包含的行:该表包含来自世界各地区共 206 个国家/地区的详细信息。具体有多少个地区?下面这条查询能回答这个问题。
结果显示,该表覆盖了 23 个不同地区,例如西欧、波利尼西亚、中东等。您可以带着自己的小问题探索这张表,沿途或许还能发现有趣的事实。现在我们来了解一下基本的 PostgreSQL
CASE结构。