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

从两张表中获取最新交易记录的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:37:26