我有这样的疑问。它从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只是同一结果记录中的另一个单元格)。
答案 0 :(得分:1)
如果每个TableB
和(EventID
或Code=5
或Code=15
或Code=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