从两张表中获取最新交易记录的SQL查询问题咨询
分析与优化你的跨表最新交易查询
首先,先拆解下你当前SQL的逻辑:它会分别对TableTester1和TableTester2按小写后的邮箱分组,每组内按reserve_date倒序排序,取每组的第一条记录,再用UNION合并两个结果集。返回2条结果,应该是两个表各自对应一个唯一邮箱的最新记录。
你提到需要调整查询,虽然没明确具体需求,但我整理了几种常见的业务调整场景和对应的优化方案,供你参考:
场景1:取每个邮箱在两个表中整体最新的一条记录
当前SQL的问题是,如果同一个邮箱在两个表都有记录,会返回两条(每个表各一条最新)。如果你的需求是拿到该邮箱在两个表中的绝对最新记录,需要先合并所有数据再分组排序:
SELECT * FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY lower(email) ORDER BY reserve_date DESC) AS ranking, id, reserve_date, email -- 如需展示邮箱可添加 FROM ( SELECT id, reserve_date, email FROM TableTester1 UNION ALL -- 用UNION ALL替代UNION,避免不必要的去重,提升效率 SELECT id, reserve_date, email FROM TableTester2 ) combined_data ) ranked_data WHERE ranking = 1;
场景2:需要保留原表的更多字段
当前SQL只提取了id和reserve_date,如果需要原表的其他字段,只需在子查询中明确添加或直接使用*即可:
SELECT * FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY lower(tb1.email) ORDER BY tb1.reserve_date DESC) AS ranking, tb1.* -- 提取TableTester1的所有字段 FROM TableTester1 tb1 UNION SELECT ROW_NUMBER() OVER (PARTITION BY lower(tb2.email) ORDER BY tb2.reserve_date DESC) AS ranking, tb2.* -- 提取TableTester2的所有字段 FROM TableTester2 tb2 ) ranked_data WHERE ranking = 1;
注意:如果两个表的字段结构不一致,
UNION会报错,此时需要手动指定两边一致的字段列表。
场景3:大数据量下的性能优化
如果两个表数据量较大,当前写法的全局排序可能效率偏低,可以用NOT EXISTS直接过滤出每个表中邮箱的最新记录,避免全量排序:
SELECT * FROM ( SELECT * FROM TableTester1 tb1 WHERE NOT EXISTS ( SELECT 1 FROM TableTester1 tb1_dup WHERE lower(tb1_dup.email) = lower(tb1.email) AND tb1_dup.reserve_date > tb1.reserve_date ) UNION ALL SELECT * FROM TableTester2 tb2 WHERE NOT EXISTS ( SELECT 1 FROM TableTester2 tb2_dup WHERE lower(tb2_dup.email) = lower(tb2.email) AND tb2_dup.reserve_date > tb2.reserve_date ) ) latest_records;
场景4:保留同邮箱同日期的多条记录
如果reserve_date相同的记录都需要保留,把ROW_NUMBER()换成RANK()即可(RANK()会给同日期的记录分配相同的排名):
SELECT * FROM ( SELECT RANK() OVER (PARTITION BY lower(tb1.email) ORDER BY tb1.reserve_date DESC) AS ranking, tb1.id, tb1.reserve_date FROM TableTester1 tb1 UNION SELECT RANK() OVER (PARTITION BY lower(tb2.email) ORDER BY tb2.reserve_date DESC) AS ranking, tb2.id, tb2.reserve_date FROM TableTester2 tb2 ) ranked_data WHERE ranking = 1;
如果你的调整需求不在上述场景里,可以补充具体的业务要求(比如是否需要去重、是否要合并跨表同邮箱记录等),我再给你更精准的方案。
内容的提问来源于stack exchange,提问作者Rocky
相关产品推荐
相关产品推荐

