LEFT JOIN EXISTS

时间:2012-09-05 06:48:38

标签: sql-server

我有两个表MainDetails - 他们有一对多的关系,Main中的一行可能在Details中有多行。

我正在尝试创建一个返回Main中所有信息的查询,以及Details中的关联行是否包含一组代码中的一个。当然,因为它是一对多的,Details中可能存在几个代码 - 我不想重复计算行数。我也需要做几次。

我想要的是这样的:

SELECT m.*, CASE WHEN x.ID IS NOT NULL THEN 1 ELSE 0 END AS Codes1, CASE WHEN y.ID IS NOT NULL THEN 1 ELSE 0 END AS Codes2
FROM [Main] m
LEFT JOIN EXISTS(SELECT d.ID FROM [Details] d WHERE m.ID = d.ID AND d.Code IN (<<Codes1>>)) x
LEFT JOIN EXISTS(SELECT d.ID FROM [Details] d WHERE m.ID = d.ID AND d.Code IN (<<Codes2>>)) y

有没有办法做到这一点? (这似乎应该是显而易见的,我对第n度过于复杂,但我真的在画一个空白......

3 个答案:

答案 0 :(得分:2)

从查询中删除EXISTS并添加DISTINCT

SELECT DISTINCT
   m.*, 
   CASE WHEN x.ID IS NOT NULL THEN 1 ELSE 0 END AS Codes1, 
   CASE WHEN y.ID IS NOT NULL THEN 1 ELSE 0 END AS Codes2 
FROM [Main] m 
LEFT JOIN (SELECT d.ID FROM [Details] d WHERE m.ID = d.ID AND d.Code IN (<<Codes1>>)) x 
LEFT JOIN (SELECT d.ID FROM [Details] d WHERE m.ID = d.ID AND d.Code IN (<<Codes2>>)) y 

答案 1 :(得分:0)

我认为这会奏效:

SELECT  M.*, 
        CASE WHEN C1.Codes IS NULL THEN 0 ELSE 1 END as Codes1,
        CASE WHEN C2.Codes IS NULL THEN 0 ELSE 1 END as Codes2
FROM    Main M
LEFT
JOIN    
(
    SELECT  d.Id,
            COUNT(d.Code) as Codes
    FROM    Details d
    WHERE   d.Code in (<<Codes1>>)
    GROUP 
    BY      d.Id
) C1
    ON C1.Id = M.Id
LEFT
JOIN    
(
    SELECT  d.Id,
            COUNT(d.Code) as Codes
    FROM    Details d
    WHERE   d.Code in (<<Codes2>>)
    GROUP 
    BY      d.Id
) C2
    ON C2.Id = M.Id

如果你不需要M. *那么这可能会更好:

SELECT  M.Id, 
        SUM(CASE WHEN D1.Id IS NULL THEN 0 ELSE 1 END) AS Codes1Count,
        SUM(CASE WHEN D2.Id IS NULL THEN 0 ELSE 1 END) AS Codes2Count
FROM    Main M
LEFT
JOIN    Details D1
        ON  D1.Id = M.Id 
        AND D1.Code in (<<Codes1>>)
LEFT
JOIN    Details D2
        ON  D2.Id = M.Id 
        AND D2.Code in (<<Codes2>>)
GROUP 
BY      M.Id

答案 2 :(得分:0)

这是一个简洁的代码版本,可以满足您的需求

SELECT abb1.*, abb2.mycount 
FROM Main AS abb1
    JOIN (SELECT Main.ID, COUNT(Details.ID) AS mycount
         FROM Main 
            JOIN Details on Details.ID = Main.ID
         GROUP BY Main.ID) AS abb2