SQL窗口函数如何简化复杂的逻辑判断_实战重构

张开发
2026/4/16 14:11:25 15 分钟阅读

分享文章

SQL窗口函数如何简化复杂的逻辑判断_实战重构
COALESCE 更安全简洁地取首个非空值但需类型兼容且仅识别 NULL处理空字符串需结合 NULLIFROW_NUMBER() PARTITION BY 可高效替代关联子查询实现去重取最新。用 COALESCE 替代嵌套 CASE WHEN 判断空值很多逻辑判断本质是“取第一个非空值”比如优先用用户自填地址没有就 fallback 到注册地址再没有就用默认城市。这时候写三层 CASE WHEN 不仅啰嗦还容易漏掉 IS NULL 检查。直接用 COALESCE 更安全、更短而且语义明确——它天然按顺序返回第一个非 NULL 的表达式结果。COALESCE 所有参数必须类型兼容混用字符串和数字会报错比如 COALESCE(name, 0) 在 PostgreSQL 里直接失败MySQL 里 COALESCE 对空字符串 不敏感它只认 NULL所以 COALESCE(, fallback) 返回的是 不是 fallback如果要同时处理 NULL 和空字符串得先用 NULLIF 转换COALESCE(NULLIF(trim(address), ), 未知地址)用 ROW_NUMBER() PARTITION BY 替代关联子查询去重常见需求每个用户最新一笔订单。老办法是写子查询找 MAX(created_at) 再关联但数据量一大就慢还容易因时间相同导致多条命中。窗口函数一次扫描就能搞定ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) 给每组内的记录排唯一序号再外层筛 1 就行。注意 ORDER BY 必须包含能打破并列的字段比如 created_at DESC, id DESC否则同秒创建的订单谁排第一不确定RANK() 和 DENSE_RANK() 会重复编号不适合“取最新一条”这种唯一性要求某些旧版 MySQL用 LAG() 计算环比时小心分区边界计算用户上次登录距今几天常用 LAG(login_time) OVER (PARTITION BY user_id ORDER BY login_time)。看起来没问题但实际一跑发现第一条记录的 LAG 值是 NULL——这是对的因为没“上一条”。 通义听悟 阿里云通义听悟是聚焦音视频内容的工作学习AI助手依托大模型帮助用户记录、整理和分析音视频内容体验用大模型做音视频笔记、整理会议记录。

更多文章