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

SQL三表INNER JOIN如何筛选最新日期的关联记录

三表关联查询取单ID对应最新时间最优实现

你当前的基础SQL存在两个核心问题:

  • 直接用SELECT a.*,b.*,c.*会把三张表各自的date字段全部返回,无法直接拿到跨表的最新时间
  • 没有做单ID下的最新记录过滤,一旦某个ID在单表内存在多条历史记录,三表内连接会产生笛卡尔积式的重复脏数据

结合你用的是SQL Server(dbo为SQL Server默认schema),窗口函数方案是性能最高、逻辑最清晰的实现,可以完全匹配你给出的样例输出结果,代码如下:

WITH merged_data AS (
    -- 第一步:对齐三张表字段,合并所有记录,避免直接join产生笛卡尔积
    SELECT id, location, CAST(NULL AS VARCHAR(20)) AS areacode, date FROM dbo.ISD_machines
    UNION ALL
    SELECT id, CAST(NULL AS VARCHAR(50)) AS location, areacode, date FROM dbo.ISD_systems
    UNION ALL
    SELECT id, CAST(NULL AS VARCHAR(50)) AS location, CAST(NULL AS VARCHAR(20)) AS areacode, date FROM dbo.ISD_laptops
),
ranked_data AS (
    SELECT
        id,
        location,
        areacode,
        date,
        -- 按ID分组,时间倒序排名,每个ID下最新的记录排名为1
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS time_rn,
        -- 统计每个ID在几张表中存在,等于3代表三张表都有匹配,对应原内连接逻辑
        COUNT(*) OVER (PARTITION BY id) AS match_table_cnt
    FROM merged_data
)
-- 最终聚合拿到结果
SELECT
    id,
    MAX(location) AS location,
    MAX(areacode) AS areacode,
    date
FROM ranked_data
WHERE 
    time_rn = 1 -- 只取每个ID下最新时间对应的记录
    AND match_table_cnt = 3 -- 只保留三张表都能匹配到的ID,和原INNER JOIN逻辑一致
GROUP BY id, date

方案说明

  • 性能表现:三张表仅各扫描一次,窗口函数为SQL Server原生深度优化的算子,相比「子查询查max(date)再回表join」的传统写法,减少了大量哈希匹配、回表的开销,数据量越大优势越明显
  • 逻辑匹配度:和你给出的样例结果完全一致——样例中仅LAP2002同时存在于三张表,跨表对比后最新时间为表3的15-06-2022 10:21:00,对应location为Chennai、areacode为632009,和预期输出完全匹配
  • 适配调整:如果你需要保留原SQL中用HOSTNAME、SYSTEM_NAME、NAME字段做关联的逻辑,只需要把CTE中的id替换成对应关联字段即可,核心排名取最新值的逻辑不需要改动

注意事项

  • 请确保date字段为datetime/datetime2类型,不要用字符串类型存储时间,否则排序时会按字符序比较,出现时间判断错误
  • 如果存在同一ID同一时间在多张表有记录的场景,可以把ROW_NUMBER()换成RANK(),避免漏数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:45:36