SQL联合查询后按日期降序取指定唯一ID首行问题求助
嘿,我瞅了下你的SQL语句,先揪出几个明显的语法坑,再帮你实现「Union后按日期降序取每个唯一ACCT_NBR第一行」的需求~
先说说原语句的语法错误
- WHERE子句里的
ACCT_BLK_1,'@') IN ('A')明显是笔误,应该是ACCT_BLK_1 IN ('A'),多余的,'@')完全不符合SQL语法; - 字段名
DATE是SQL关键字,最好用反引号(`)括起来,避免和数据库内置关键字冲突; - UNION要求两个子查询的字段数量、类型、顺序完全一致,你第二个子查询只写了
SELECT DISTINCT ACC...,得补全对应字段,不然会报字段不匹配的错误。
修正后的完整SQL实现
我用CTE(公共表表达式)+窗口函数的方式帮你实现需求,逻辑更清晰:
WITH unioned_data AS ( -- 第一个子查询:修正语法错误,统一字段别名 SELECT ACCT_NBR, ACCT_BLK_1 AS BLK_CDE, BLK_RSN_1 AS BLK_CDE_RSN, BLK_CDE_1_CHG_DT AS CLOSED_DT FROM TABLE_1 WHERE ACCT_BLK_1 IN ('A') AND `DATE` = CURRENT_DATE - 1 AND BLK_CDE_1_CHG_DT BETWEEN '2018-04-01' AND '2018-04-10' UNION -- 第二个子查询:请根据你的实际表结构补全字段和过滤条件,确保和第一个子查询字段一致 SELECT ACCT_NBR, ACCT_BLK_2 AS BLK_CDE, -- 示例:替换成你实际的字段名 BLK_RSN_2 AS BLK_CDE_RSN, BLK_CDE_2_CHG_DT AS CLOSED_DT FROM TABLE_2 -- 替换成你实际的表名 WHERE ACCT_BLK_2 IN ('A') -- 示例:替换成你实际的过滤条件 AND `DATE` = CURRENT_DATE - 1 ), ranked_data AS ( -- 给每个ACCT_NBR分组,按CLOSED_DT降序排,标记行号 SELECT *, ROW_NUMBER() OVER (PARTITION BY ACCT_NBR ORDER BY CLOSED_DT DESC) AS rn FROM unioned_data ) -- 筛选每个ACCT_NBR的最新日期记录(行号=1) SELECT ACCT_NBR, BLK_CDE, BLK_CDE_RSN, CLOSED_DT FROM ranked_data WHERE rn = 1;
额外说明
- 如果你不需要自动去重,可以把
UNION换成UNION ALL,执行效率更高;原语句里的DISTINCT其实可以去掉,因为UNION本身会自动去重; - 如果你的数据库不支持
EXCEPT (rn)(比如MySQL 8.0以前),就直接列出需要的字段,不要用SELECT *; - 不同数据库的日期函数可能有差异,比如Oracle用
SYSDATE,SQL Server用GETDATE(),请根据你的数据库调整CURRENT_DATE的写法。
内容的提问来源于stack exchange,提问作者vjpkr
相关产品推荐
相关产品推荐

