数据库中的COALESCE函数用于返回参数列表中第一个非NULL值,若所有参数均为NULL则返回NULL

Oracle/MySQL/SQLServer/Postgres/openGauss等关系型数据库中的COALESCE函数用于返回参数列表中第一个非NULL值,若所有参数均为NULL则返回NULL。

1、基本语法

sql 复制代码
COALESCE(expr1, expr2, ..., exprn),支持任意数量参数。
  • 从左到右依次判断 value1, value2, value3, ...
  • 返回 第一个不是 NULL 的值
  • 所有都为 NULL,则返回 NULL

2、 典型应用场景包括‌:

2.1、示例1

  • 给字段设置显示默认值
sql 复制代码
SELECT COALESCE(nick_name, real_name, '匿名用户') AS display_name
FROM users;

含义:

  • 如果 nick_name 不为 NULL → 用 nick_name
  • 否则如果 real_name 不为 NULL → 用 real_name
  • 否则用 '匿名用户'

2.2、 避免聚合结果为 NULL

sql 复制代码
SELECT COALESCE(SUM(amount), 0) AS total_amount
FROM orders
WHERE user_id = 123;

如果这个用户没有订单,SUM(amount) 为 NULL,使用 COALESCE 返回 0。

2.3、构造带默认值的查询条件或字段

sql 复制代码
SELECT COALESCE(phone, '无手机号') AS phone_display
FROM customers;

3、和 NVL / IFNULL 的对比

  • COALESCE:标准 SQL,支持多个参数,很多数据库(PostgreSQL/openGauss/GaussDB、MySQL、Oracle 等)都支持
  • NVL(expr1, expr2)(Oracle):只支持两个参数,相当于 COALESCE(expr1, expr2)
  • IFNULL(expr1, expr2)(MySQL):也只支持两个参数

4、小注意点

所有参数的数据类型要能相互兼容,否则会报类型错误

在 WHERE 里用时,只是返回值,不会"忽略 NULL 行",要配合条件使用,例如:

sql 复制代码
SELECT *
FROM users
WHERE COALESCE(status, 'inactive') = 'active';

5、gaussdb中使用COALESCE

sql 复制代码
-- ============================================
-- 1. 函数测试
-- ============================================
-- 创建函数:计算用户总消费
CREATE OR REPLACE FUNCTION test_schema.get_user_total_spent(p_user_id INT)
RETURNS DECIMAL(10, 2) AS $$
DECLARE
    v_total DECIMAL(10, 2);
BEGIN
    SELECT COALESCE(SUM(total_amount), 0) INTO v_total
    FROM test_schema.tb_orders
    WHERE user_id = p_user_id AND order_status = 'completed';
    
    RETURN v_total;
END;
$$ LANGUAGE plpgsql;

-- 测试函数
SELECT test_schema.get_user_total_spent(1) AS user1_total_spent;
sql 复制代码
-- ============================================
-- 2. 视图测试
-- ============================================
-- 创建视图
CREATE OR REPLACE VIEW test_schema.v_user_order_summary AS
SELECT 
    u.user_id,
    u.username,
    u.email,
    COUNT(o.order_id) AS total_orders,
    COALESCE(SUM(CASE WHEN o.order_status = 'completed' THEN o.total_amount ELSE 0 END), 0) AS completed_amount,
    COALESCE(SUM(CASE WHEN o.order_status = 'pending' THEN o.total_amount ELSE 0 END), 0) AS pending_amount
FROM test_schema.tb_users u
LEFT JOIN test_schema.tb_orders o ON u.user_id = o.user_id
GROUP BY u.user_id, u.username, u.email;

-- 查询视图
SELECT * FROM test_schema.v_user_order_summary ORDER BY completed_amount DESC;
相关推荐
小二·6 小时前
RAG + 向量数据库实战:ChromaDB / Milvus / FAISS 选型与性能横评
数据库·milvus·faiss
矜持的左手6 小时前
电子小白的枕边书:电子学(The Art of Electronics)
数据库·restful
吴声子夜歌6 小时前
Redis 5.x——布隆过滤器
数据库·redis·缓存
Albert Tan7 小时前
Oracle EBS 外部应用节点-OOM
oracle·oracle ebs
蓝天下的守望者7 小时前
svt_apb_if里的宏定义问题
运维·服务器·数据库
上海云盾-小余7 小时前
网站频繁遭遇 SQL 注入溯源与原生漏洞修复全流程总结
数据库·sql
数据库小学妹7 小时前
国家区域医疗中心国产化改造实战:数据库选型、跨院区数据互通与踩坑经验
数据库·国产数据库·数据库选型·医疗信息化·信创数据库·医疗信创
AllData公司负责人8 小时前
数据库同步平台|AIIData数据中台实现OceanBase、达梦数据库、OpenGauss、人大金仓、Hive、TDengine 一键接入Doris
大数据·数据库·hive·mysql·oceanbase·tdengine
2603_954708319 小时前
全维度容错设计,打造微电网安全运行屏障
服务器·网络·数据库·人工智能·分布式·安全