加入T-SQL中的顶级记录

时间:2011-08-10 16:40:04

标签: sql tsql join

SELECT MD.*, Contact.FirstName 
FROM MerchantData MD
JOIN Merchant M ON M.MerchID = MD.MerchID   
JOIN (SELECT TOP 1 * FROM Location WHERE Location.BusID = MD.BusID) L ON L.BusID=MD.BusID
AND L.Deleted = 0
JOIN Contact ON Contact.ContactID = L.PrincipalID

我正在使用SQLSERVER 2008并尝试编写此SQL语句。有时候busid有多个位置,我想只加入第一个找到的位置。我在“Location.BusID = MD.BusID”部分收到错误,因为MD.BusID无法绑定。是否可以在此联接中的嵌套选择语句中使用MD表,还是有另一种方法可以实现此目的?

我正在通过列列表中的嵌套查询来放置数据,以便在那里干净地抓取联系人数据。

4 个答案:

答案 0 :(得分:9)

我认为有一个完整结果集的子查询会更简单:

SELECT MD.*, Contact.FirstName 
FROM MerchantData MD
JOIN Merchant M ON M.MerchID = MD.MerchID   
JOIN (SELECT BusID, MAX(PrincipalID)
      FROM Location
      WHERE Deleted = 0
      GROUP BY BusID) L ON L.BusID=MD.BusID
JOIN Contact ON Contact.ContactID = L.PrincipalID

BusID中每JOIN段仍有一条记录,但它没有相关性。

答案 1 :(得分:4)

SELECT MD.*, Contact.FirstName  
FROM MerchantData MD 
JOIN Merchant M ON M.MerchID = MD.MerchID    
CROSS APPLY (SELECT TOP 1 * FROM Location WHERE BusID = MD.BusID AND DELETED = 0) L
JOIN Contact ON Contact.ContactID = L.PrincipalID 

答案 2 :(得分:2)

这是“每组最高n”问题。这个问题将指导您:

SQL Server query select 1 from each sub-group

你会想做这样的事情:

SELECT MD.* ,
       Contact.FirstName 
FROM MerchantData MD
JOIN Merchant     M ON M.MerchID = MD.MerchID   
JOIN ( select * ,
              seq = rank() over( partition by BusID order by BusID , ... )
       from Location
       where L.Deleted = 0
     ) L on L.BusID = MD.BusID
        and seq     = 1
JOIN Contact ON Contact.ContactID = L.PrincipalID

虚拟表表达式每个BusID最多返回1个位置(如果BusID没有未删除的位置,则返回0)。

答案 3 :(得分:0)

尝试找出我会尝试的错误。看看它是否可以匹配Location.BusID = MD.BusID。

    SELECT MD.*, Contact.FirstName 
    FROM MerchantData MD
    JOIN Merchant M ON M.MerchID = MD.MerchID   
    JOIN Location On Location.BusID = MD.BusID 

您不使用*所以使用

    SELECT TOP 1 Location.BusID FROM Location WHERE Location.BusID = MD.BusID 

一旦你的语法有效。

你知道一旦你开始工作,它只会匹配“第一”行,然后检查它是否被删除。问题是没有“第一”行的命令是任意的。即使表上有聚簇索引,也没有保证排序而没有order by子句。要获得可重复的答案,您需要进行排序。但是如果你正在排序并且只想要顶行,那么MAX或MIN和一组更直接。

如果您只想要拥有一个或多个已删除位置的商家,那么以下内容应该可以运行,但您需要分组该列的列。如果两个已删除的位置具有不同的联系人姓名,则它将报告每个位置。所以,这可能不是你想要的。

    SELECT MD.col1, MD.col2, Contact.FirstName 
    FROM MerchantData MD
    JOIN Merchant M ON M.MerchID = MD.MerchID   
    JOIN Location L
       ON  L.BusID = MD.BusID
       AND L.Deleted = 0
    JOIN Contact ON Contact.ContactID = L.PrincipalID 
    GROUP BY MD.col1, MD.col2, Contact.FirstName 
相关问题