【问题标题】:Join on MAX value of one part of composite key加入组合键的一部分的 MAX 值
【发布时间】:2012-03-02 09:32:57
【问题描述】:

我试图通过 LEFT OUTER JOINing 两个表来比较两个表,并在右表中找到任何不匹配的结果。问题是我有一个 TicketNo、ItemNo 和 UniqueID 的复合键,我只需要比较任何给定 TicketNo 的唯一 ID 最高的行。

我需要这些数据,以便我的程序知道它是否需要更新工作副本表以及如果需要更新哪些行。

基本上我想要的是这样的:

SELECT TicketNo
FROM History t1
LEFT OUTER JOIN Working t2 on 
max(t1.[UniqueID])=t2.[UniqueID] 
AND t1.[TicketNo]=t2.[TicketNo]
AND t1.[ItemNo]=t2.[ItemNo]
WHERE t2.[TicketNo] IS NULL 

但我不能在这里使用聚合函数 max。我不知道如何使用子查询(或不能使用 CTE,但我更喜欢子查询)来仅获取给定 TicketNo 的最大唯一 ID。我不能只加入表中最高的 uniqueID。

我的数据看起来像这样,假设有两个重复:

TicketNo    UniqueID    ItemNo
15         1270662207   1
15         1184857061   1

在这种情况下,我只希望 first 行返回。我不在乎我的工作表是否有带有TicketNo 15 的旧行。

【问题讨论】:

    标签: sql sql-server sql-server-2005 join


    【解决方案1】:

    解决这个问题的技术与分组最大模式有关。在这种情况下,您使用它在不同的表而不是同一个表中查找与聚合结果的最大值匹配的完整行。

    但想法是一样的——您必须使用派生表或子查询来获取结果。

    以下是派生表方法的示例:

    SELECT d.TicketNo FROM 
     (SELECT TicketNo, ItemNo, MAX(UniqueID) AS maxid FROM History t1 GROUP BY TicketNo, ItemNo) AS d 
     LEFT JOIN Working t2 ON d.TicketNo=t2.TicketNo AND d.ItemNo=t2.ItemNo AND d.maxid=t2.UniqueID 
    WHERE t2.TicketNo IS NULL;
    

    有关更多信息,请参阅以下链接:

    http://jan.kneschke.de/projects/mysql/groupwise-max/

    http://dev.mysql.com/doc/refman/5.5/en/example-maximum-column-group-row.html

    【讨论】:

    • 您的查询有几个小问题 - (1) 列不明确,因为您的 SELECT 列表没有表前缀(应该是 d.TicketNo) (b) @987654325 中的多部分标识符问题@ 子句 - 你将 Working 别名为 t2 然后你的标准指定 t1 (使用有意义的别名而不是 t1、t2、t3 等的一个原因是有意义的)。您似乎还缺少连接子句之一 (ItemNo)。
    【解决方案2】:
    DECLARE @History TABLE(UniqueID INT, TicketNo INT, ItemNo INT);
    DECLARE @Working TABLE(UniqueID INT, TicketNo INT, ItemNo INT);
    
    INSERT @History SELECT 15,1270662207,1
          UNION ALL SELECT 15,1184857061,1;
    
    INSERT @Working SELECT 15,1184857061,1;
    
    SELECT h.TicketNo, h.UniqueID
    FROM 
    (
        SELECT TicketNo, ItemNo, MAX(UniqueID) AS UniqueID
        FROM @History GROUP BY TicketNo, ItemNo
    ) AS h
    LEFT OUTER JOIN 
    @Working AS w
        ON h.TicketNo = w.TicketNo
        AND h.ItemNo = w.ItemNo
        AND h.UniqueID = w.UniqueID
    WHERE w.TicketNo IS NULL;
    

    结果:

    TicketNo    UniqueID
    ----------- -----------
    1270662207  15
    

    【讨论】:

    • 嘿,你不必将它与我的数据相匹配。不过,它就像一个魅力。
    【解决方案3】:

    尝试以这种方式使用 GROUP BY 和 ORDER BY 子句:

    SELECT TicketNo
    FROM History t1
    LEFT OUTER JOIN Working t2 on 
    t1.[UniqueID]=t2.[UniqueID] 
    AND t1.[TicketNo]=t2.[TicketNo]
    AND t1.[ItemNo]=t2.[ItemNo]
    WHERE t2.[TicketNo] IS NULL
    GROUP BY t1.[TicketNo], t1.[ItemNo]
    ORDER BY t1.[UniqueID] DESC
    

    【讨论】:

    • 如果不聚合 UniqueID,Group by 将无法工作。另外我需要一个不匹配的结果集,所以我不能只对结果进行排序,我需要结果不包括非 MAX UniqueIDs
    猜你喜欢
    • 2015-09-27
    • 2021-08-11
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多