如果我理解正确的问题,你想一个10×20的结果集是这样的:
CarID | Test1 | Test2 | .... | Test20
-------------------------------------------------------
1 | NULL | Fail | .... | true
2 | 2 | Pass | .... | false
为此,我将利用SQL-Server 2008的PIVOT
函数。
WITH Results AS
( SELECT cars.CarID,
TestName,
TestValue
FROM Cars
CROSS JOIN SafetyTests s
LEFT JOIN TestResults res
ON res.CarID = Cars.CarID
AND res.TestID = s.TestID
)
SELECT *
FROM Results
PIVOT
( MAX(TestValue)
FOR TestName IN ([TesT1], [Test2], [Test3], [Test4])
-- LIST ALL 20 TEST NAMES HERE
) pvt
这样做的缺点是,你必须明确地列出所有的测试名称摆动,否则他们将不会显示为列,但它是可以动态地做到这一点。下面的查询基本上与上面的查询完全相同,但是我已经动态生成了所有列名的列表并将它们插入到查询中。
DECLARE @SQL NVARCHAR(MAX) = ''
SELECT @SQL = @SQL + ',' + QUOTENAME(TestName)
FROM SafetyTests
SET @SQL = 'WITH Results AS
( SELECT Cars.CarID,
TestName,
TestValue
FROM Cars
CROSS JOIN SafetyTests s
LEFT JOIN TestResults res
ON res.CarID = Cars.CarID
AND res.TestID = s.TestID
)
SELECT *
FROM Results
PIVOT
( MAX(TestValue)
FOR TestName IN (' + STUFF(@SQL, 1, 1, '') + ')
) pvt'
EXECUTE SP_EXECUTESQL @SQL
SQL Fiddle
砸,绝对的感谢!我不知道有交叉连接这样的事情。当我在上周看到加入时,我从未在W3Schools页面上看到过这一点!它有另一个名字,如全联接等? – mezamorphic
没有完整连接是不同的连接 - 交叉连接只是行的笛卡尔乘积,不需要任何连接条件(我更新了左连接,因为它缺少汽车连接来测试结果)。CROSS JOIN总是给出(左边的行数)*(右边的行数) – Charleh
在我的db上模拟表格并添加了一个图像来证明它有效:) – Charleh