跳至主要内容

如何在 SQL 中使用 COALESCE() 函数(含示例)

学习如何使用 SQL 的 COALESCE() 函数处理空值、合并列,并通过真实示例与技巧清理数据。
· 5分钟 阅读

使用 AI 探索

在处理真实世界的数据时,缺失值几乎不可避免。无论您是在清洗数据集还是合并列,SQL 都提供了一个简洁而强大的解决方案:COALESCE() 函数。本教程将演示 COALESCE() 的工作原理、适用场景,以及如何通过实用示例加以应用——只需几行 SQL 即可。

SQL 中的 COALESCE() 是什么?

SQL 中的 COALESCE() 函数会从一组表达式中返回第一个非空值(non-null)。如果所有值都为 null,则返回 null。它通常用于处理缺失值,或将多列合并为一个回退输出。

何时应使用 COALESCE()?

当需要将多个列的值合并为一个时,此函数非常有用。

例如,名为 users 的表包含用户的 work_email 和 personal_email 值。

使用 COALESCE() 函数,我们可以创建一个名为 email 的列:如果用户的 work_email 不为 null,则显示该值;否则显示 personal_email。

user_id

work_email

personal_email

COALESCE() of

work_email and

personal_email

1

[email protected]

null

[email protected]

2

null

[email protected]

[email protected]

3

[email protected]

[email protected]

[email protected]

COALESCE() 的语法

COALESCE(value_1, value_2, ...., value_n)

COALESCE() 函数至少接收一个值(value_1)。它将从左到右返回列表中第一个非空值。

例如,它会先检查 value_1 是否为 null。如果不是,则返回 value_1。否则检查 value_2 是否为 null,如此循环直到遍历完整个列表。

COALESCE() 可与列、表达式或常量一起使用。

COALESCE() 的实用示例

在线运行和编辑此教程中的代码

运行代码

示例 1:将 null 替换为常量

考虑表 countries,其中包含国家及其国庆日的列表。部分国庆日值为 null。COALESCE() 会将 national_day 中的缺失值填充为常量字符串 'Unknown'。

SELECT
   country_id,
   name, 
   national_day,
   COALESCE(national_day, 'Unknown') AS national_day_coalesced
FROM countries
ORDER BY country_id

结果如下:

country_id

name

national_day

national_day_coalesced

1

Aruba

null

Unknown

2

Afghanistan

1919-08-19T00:00:00.000Z

1919-08-19

3

Angola

1975-11-11T00:00:00.000Z

1975-11-11

4

Anguilla

1967-05-30T00:00:00.000Z

1967-05-30

可以看到,national_day 中的 null 值被常量 Unknown 所替换。

示例 2:在两列之间进行选择

我们有一个名为 products 的表,包含产品名称及描述。部分描述过长(超过 60 个字符)。在这种情况下,我们用产品名称替代描述。

下面的查询使用 CASE 将过长的描述转换为 NULL,然后用 COALESCE() 回退到产品名称。

SELECT DISTINCT
   product_name,
   description,
   COALESCE(
      CASE WHEN 
         LENGTH(description) >= 60 
         THEN NULL 
         ELSE description 
         END, 
      product_name) product_name_or_description
FROM products

结果如下:

product_name

description

product_name_or_description

G.Skill Ripjaws V Series

"Speed:DDR4-3200,Type:288-pin DIMM,CAS:14Module:4x16GBSize:64GB"

G.Skill Ripjaws V Series

G.Skill Ripjaws V Series

"Speed:DDR4-3200,Type:288-pin DIMM,CAS:15Module:4x16GBSize:64GB"

G.Skill Ripjaws V Series

Asus X99-E-10G WS

"CPU:LGA2011-3,Form Factor:SSI CEB,RAM Slots:8,Max RAM:128GB"

"CPU:LGA2011-3,Form Factor:SSI CEB,RAM Slots:8,Max RAM:128GB"

Supermicro X9SRH-7TF

"CPU:LGA2011,Form Factor:ATX,RAM Slots:8,Max RAM:64GB"

"CPU:LGA2011,Form Factor:ATX,RAM Slots:8,Max RAM:64GB"

可以看到,如果 description 过长,product_name_or_description 列会显示 product_name;否则显示 description。

示例 3:多列回退逻辑

我们可以在示例 2 的基础上更进一步。假设当前有两个需求:

  • 如果 description 的长度小于 60,则显示 description。
  • 否则,检查 product_name 的长度是否小于 20;若是,则显示 product_name。
  • 否则,显示 product。
SELECT DISTINCT
   product_name,
   description,
   COALESCE(
      CASE 
         WHEN LENGTH(description) > 50
         THEN NULL
         ELSE description
      END,
   CASE 
      WHEN LENGTH(product_name) > 14
      THEN NULL
      ELSE product_name
   END,
'product') AS product_name_or_description
FROM products
ORDER BY product_name

结果如下:

product_name

description

product_name_or_description

ADATA ASU800SS-128GT-C

Series:Ultimate SU800,Type:SSD,Capacity:128GB,Cache:N/A

product

ADATA ASU800SS-512GT-C

Series:Ultimate SU800,Type:SSD,Capacity:512GB,Cache:N/A

product

AMD 100-5056062

Chipset:Vega Frontier Edition Liquid,Memory:16GBCore Clock:1.5GHz

product

AMD 100-505989

Chipset:FirePro W9100,Memory:32GBCore Clock:930MHz

Chipset:FirePro W9100,Memory:32GBCore Clock:930MHz

可以看到,product_name_or_description 列会根据 product_name 与 description 的长度显示其一。

支持的 SQL 引擎

COALESCE() 适用于 SQL Server(自 2008 起)、Azure SQL Database、Azure SQL Data Warehouse、Parallel Data Warehouse、BigQuery 和 Amazon RedShift。

相关 SQL 函数

总结

COALESCE() 函数是处理空值并简化 SQL 查询的多面手。无论您是在用默认值替换缺失数据,还是将多列合并为一列,COALESCE() 都能让您的逻辑保持清晰易读。

准备进一步提升您的 SQL 技能吗?欢迎浏览 DataCamp 上这些适合初学者且有助于职业发展的课程:

FAQs

如果 COALESCE() 中的所有值都是 NULL,会发生什么?

如果传给 COALESCE() 函数的所有参数都为 NULL,该函数将返回 NULL。

COALESCE() 与 ISNULL() 或 IFNULL() 有何不同?
  • ISNULL()(SQL Server)和 IFNULL()(MySQL、SQLite)只接受两个参数。
  • COALESCE() 可接受多个参数,并且在各 SQL 方言中更为标准。

  • COALESCE() 属于 ANSI SQL 标准,而 ISNULL() 和 IFNULL() 则是特定数据库实现。

我可以将 COALESCE() 与表达式或函数一起使用吗?

可以,您可以在 COALESCE() 中使用列名、字面量、函数或表达式。

COALESCE(LOWER(name), 'unknown')
使用 COALESCE() 会有性能损耗吗?

一般来说不会——COALESCE() 是高效的。不过,如果与复杂表达式或大型查询一起使用,具体写法可能导致数据库评估的表达式多于必要部分,从而产生一定开销。

COALESCE() 能处理不同数据类型吗?

可以,但所有参数应能隐式转换为一个共同的数据类型。否则,可能会根据您的 SQL 引擎出现类型转换错误。

我可以嵌套使用 COALESCE() 吗?

可以,您可以进行嵌套,尽管这很少有必要,因为 COALESCE() 已经可以处理多个参数:

COALESCE(col1, COALESCE(col2, 'default'))

其等价于:

COALESCE(col1, col2, 'default')

主题