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

如何用MySQL查询按CNPJ分组、END_DATE排序的上一条TARGET_CNPJ

需求可实现性说明

该需求完全可以通过MySQL查询实现,根据你使用的MySQL版本不同有两种落地方案:

方案1:MySQL 8.0+ 版本(推荐,性能最优)

直接使用窗口函数LAG()即可实现,核心排序逻辑通过IF(END_DATE IS NULL,1,0)控制空值排在末尾,符合你的需求。
示例查询语句:

SELECT 
  CNPJ,
  TARGET_CNPJ,
  END_DATE,
  LAG(TARGET_CNPJ, 1, '无前置TARGET_CNPJ') OVER (
    PARTITION BY CNPJ 
    ORDER BY IF(END_DATE IS NULL, 1, 0) ASC, END_DATE ASC
  ) AS LAST_CNPJ
FROM 你的实际表名;

方案2:MySQL 5.x 及更低版本(无窗口函数支持)

可以通过用户变量生成排序序号后自关联实现,示例查询语句:

SELECT 
  t1.CNPJ,
  t1.TARGET_CNPJ,
  t1.END_DATE,
  IFNULL(t2.TARGET_CNPJ, '无前置TARGET_CNPJ') AS LAST_CNPJ
FROM (
    SELECT 
      *,
      @rn := IF(@cur_cnpj = CNPJ, @rn + 1, 1) AS row_num,
      @cur_cnpj := CNPJ
    FROM 你的实际表名
    CROSS JOIN (SELECT @rn := 0, @cur_cnpj := '') AS init_vars
    ORDER BY CNPJ, IF(END_DATE IS NULL, 1, 0) ASC, END_DATE ASC
) AS t1
LEFT JOIN (
    SELECT 
      *,
      @rn2 := IF(@cur_cnpj2 = CNPJ, @rn2 + 1, 1) AS row_num,
      @cur_cnpj2 := CNPJ
    FROM 你的实际表名
    CROSS JOIN (SELECT @rn2 := 0, @cur_cnpj2 := '') AS init_vars
    ORDER BY CNPJ, IF(END_DATE IS NULL, 1, 0) ASC, END_DATE ASC
) AS t2 ON t1.CNPJ = t2.CNPJ AND t1.row_num = t2.row_num + 1;

补充说明

  • 排序逻辑中的IF(END_DATE IS NULL,1,0)也可以替换为END_DATE IS NULL ASC,在多数MySQL分支下效果一致,写法更简洁
  • 如果需要将生成的LAST_CNPJ持久化存储到表中,只需要在上述查询基础上增加INSERT或者UPDATE逻辑即可

内容的提问来源于stack exchange,提问作者Bruno Aarão

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:36:08