T-SQL删除多个LEFT JOIN

时间:2011-10-07 09:45:55

标签: sql sql-server tsql left-join

我有这样的疑问。它从TableA返回ColA和ColB,从表Users返回UserName。然后它显示TableB中的几个字段作为结果的附加列。它有效,但有没有比使用这些多LEFT JOINS更好的方法?

SELECT a.COlA, a.ColB, u.UserName,
b1.Value,
b2.Value,
b3.Value,
b4.Value,

FROM TableA a JOIN Users u ON a.UserId = u.UserId
    LEFT JOIN TableB b1 ON a.EventId = b1.EventId AND b1.Code = 5
    LEFT JOIN TableB b2 ON a.EventId = b2.EventId AND b2.Code = 15
    LEFT JOIN TableB b3 ON a.EventId = b3.EventId AND b3.Code = 18
    LEFT JOIN TableB b4 ON a.EventId = b4.EventId AND b4.Code = 40

WHERE (a.UserId = 3) ORDER BY u.UserName ASC

TableB看起来像:

Id | EventId | Code | Value
----------------------------
1  |    1    |  5   | textA
2  |    1    |  15  | textB
3  |    1    |  18  | textC

有时缺少代码但是对于每个事件都没有重复的代码(因此每个LEFT JOIN只是同一结果记录中的另一个单元格)。

3 个答案:

答案 0 :(得分:1)

如果每个TableB和(EventIDCode=5Code=15Code=18只有一个Code=40行,那么您可以测试此查询:

;WITH SourceCTE
AS
(
    SELECT a.COlA, a.ColB, u.UserName, b.Code, b.Value
    FROM TableA a JOIN Users u ON a.UserId = u.UserId
    INNER /*or LEFT OUTER*/ JOIN TableB b ON a.EventId = b1.EventId AND b.Code IN (5,15,18,40)
    WHERE (a.UserId = 3) ORDER BY u.UserName ASC
)
SELECT  pvt.CodA, pvt.ColB, pvt.UserName
    ,pvt.[5]  AS b1Value
    ,pvt.[15] AS b2Value
    ,pvt.[18] AS b3Value
    ,pvt.[40] AS b4Value
FROM    SourceCTE src
PIVOT   (MAX(src.Value) FOR src.Code IN ([5],[15],[18],[40])) pvt;

注意:如果您有SQL Server 2008,则可以在EventID上创建唯一的过滤索引,其中Value字段包含一个过滤器:WHERE Code IN (5,15,18,40)

答案 1 :(得分:1)

SELECT 
  a.COlA, a.ColB, u.UserName
  ,MAX(CASE WHEN b.Value = 5 THEN b.value ELSE 0 END) AS V5
  ,MAX(CASE WHEN b.Value = 15 THEN b.value ELSE 0 END) AS V15 
  ,MAX(CASE WHEN b.Value = 18 THEN b.value ELSE 0 END) AS V18 
  ,MAX(CASE WHEN b.Value = 40 THEN b.value ELSE 0 END) AS V45 
  ,COUNT(CASE WHEN b.Value not IN (5,15,18,40) THEN 1 ELSE NULL END) AS CountVOther
FROM TableA a 
INNER JOIN Users u ON a.UserId = u.UserId
LEFT  JOIN TableB b ON (a.EventId = b.EventId)
WHERE (a.UserId = 3) 
GROUP BY a.colA, a.colB, u.Username
ORDER BY u.UserName ASC

答案 2 :(得分:1)

我无法理解你为什么要改变一些有效的东西,但这是另一种方式(那些LEFT加入,但以不同的方式):

SELECT a.COlA, a.ColB, u.UserName,
  ( SELECT b.Value FROM TableB b WHERE a.EventId = b.EventId AND b.Code = 5 ),
  ( SELECT b.Value FROM TableB b WHERE a.EventId = b.EventId AND b.Code = 15 ),
  ( SELECT b.Value FROM TableB b WHERE a.EventId = b.EventId AND b.Code = 18 ),
  ( SELECT b.Value FROM TableB b WHERE a.EventId = b.EventId AND b.Code = 40 )

FROM TableA a JOIN Users u ON a.UserId = u.UserId

WHERE (a.UserId = 3) 

ORDER BY u.UserName ASC