You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MySQL的FIRST_VALUE、LAST_VALUE窗口函数中实现IGNORE NULLS?

在MySQL窗口函数中实现IGNORE NULLS效果

MySQL的FIRST_VALUE、LAST_VALUE等窗口函数本身不支持IGNORE NULLS参数,要实现忽略NULL值取第一个/最后一个非空值的效果,可通过以下几种方法实现。

场景说明

现有sales表结构及数据如下:

SaleIDCustomerIDSaleRegion
17CITY A
210NULL
310NULL
47CITY A
510CITY B
610CITY C

需求:按CustomerID分区,为每一行获取该分区内SaleRegion的第一个非空值,期望输出:

CustomerIDFIRST_VALUE(SALEREGION)
7CITY A
7CITY A
10CITY B
10CITY B
10CITY B

方法1:排序调整结合FIRST_VALUE

通过ORDER BY将非空值行前置,同时扩展窗口范围覆盖整个分区,确保即使当前行前全是NULL,也能取到分区内第一个非空值:

SELECT
  CustomerID,
  FIRST_VALUE(SaleRegion) OVER (
    PARTITION BY CustomerID
    ORDER BY CASE WHEN SaleRegion IS NOT NULL THEN SaleID ELSE 999999 END
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  ) AS `FIRST_VALUE(SALEREGION)`
FROM sales
ORDER BY CustomerID, SaleID;

逻辑说明

  • CASE WHEN SaleRegion IS NOT NULL THEN SaleID ELSE 999999 END:让非空值行按原SaleID排序,NULL值行被排到末尾,保证第一个非空值成为窗口内第一行。
  • ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING:将窗口范围设为整个分区,确保所有行都能获取到分区内的第一个非空值。

方法2:子查询预取非空值再关联

先通过子查询找到每个CustomerID对应的第一个非空SaleRegion,再与原表关联实现值的广播:

WITH first_non_null_region AS (
  SELECT
    CustomerID,
    SaleRegion
  FROM sales
  WHERE SaleRegion IS NOT NULL
  GROUP BY CustomerID, SaleRegion
  HAVING MIN(SaleID) = SaleID
)
SELECT
  s.CustomerID,
  fnnr.SaleRegion AS `FIRST_VALUE(SALEREGION)`
FROM sales s
JOIN first_non_null_region fnnr ON s.CustomerID = fnnr.CustomerID
ORDER BY s.CustomerID, s.SaleID;

逻辑说明

  • 子查询通过MIN(SaleID) = SaleID筛选出每个CustomerID下最早出现的非空SaleRegion。
  • 关联原表后,将该非空值映射到对应CustomerID的所有行上。

方法3:聚合窗口函数(适用于任意非空值场景)

如果不需要严格按顺序取第一个,仅需任意一个非空值,可直接用MAX()/MIN()窗口函数:

SELECT
  CustomerID,
  MAX(SaleRegion) OVER (PARTITION BY CustomerID) AS `FIRST_VALUE(SALEREGION)`
FROM sales
ORDER BY CustomerID, SaleID;

注:此方法会取分区内SaleRegion的最大值,若需最小值则用MIN(),仅适用于对非空值顺序无要求的场景。

内容的提问来源于stack exchange,提问作者user17276231

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:44:59