动态 Transposing/Pivoting SQL 数据

Dynamically Transposing/Pivoting SQL Data

我很抱歉问这个问题,因为这个主题有很多,但我一直在寻找一般的 Pivot 问题,但由于我正在处理的一个额外的维度而没有找到解决方案,我无法理解它。 要确定 "experience" 的船员一起比赛(这是我必须处理的最简单的说明),我需要找出给定的比赛,船员的任何部分参加过哪些先前的比赛 -当然,以用户友好的形式。 如果你不想通读结构,这里是 the SQL Fiddle Shortcut 我有联系人、汽车和比赛作为简单的实体。然后是将汽车与比赛联系起来的条目。和 Crews,由参加比赛的给定汽车中的联系人组成。

现在,对于给定的参赛作品(也就是给定比赛中的给定赛车),我需要找到该车参加过的所有先前比赛,并比较当前的哪些车手可能参加过。

例如,对于条目 ID 5(== "Fast Car" 在比赛 "Current Race" 中)我需要列出机组人员名单并打 X 标记,如果他们也参加过任何以前的比赛(==比赛 ID < 要检查的 ID) 在同一辆车中 "Fast Car".

我正在寻找的最终结果是这样的 - 虽然 "Current Race" 列是多余的,因为无论如何这是检查的起点。

                Current Race | Old Race | Even Older Race
Gladys Friday       X             X            X
Mandy Lifeboats     X             X            X
Justin Case         X       
Candy Barr          X       
Harvey Theryet      X             X            X

如果你能帮助我,那就太好了,谢谢!

假设一个联系人在每场比赛中只能出现一次,对比赛名称进行 COUNT 将产生一个二进制 table 来判断一个人何时出现在比赛中。如果出于某种原因,同一个人可以多次参加同一场比赛,那么您只会得到一个大于 1 的数字。

SELECT *
FROM (
  SELECT ContactName, RaceName FROM [dbo].[Entries] AS e 
    INNER JOIN [dbo].[Races] AS r ON [e].[Races_ID] = r.[ID]
    INNER JOIN [dbo].[Cars] AS c ON e.[Cars_ID] = c.[ID]
    LEFT JOIN Crews ON e.ID = Crews.Entries_ID
    LEFT JOIN Contacts ON [Contacts].[ID] = Crews.Contacts_ID
) src
PIVOT (
    COUNT(RaceName)
    FOR RaceName IN ([Current Race], [Old Race], [Even Older Race])
) pvt

您可以使用动态查询来执行此操作,该查询将 'adapt' 用于结果将包含的任何比赛。这是一个示例,它给出的结果与您的示例相同:

DECLARE @entry INT, @race INT, @car INT, @races VARCHAR(8000), @query NVARCHAR(MAX)
SET @entry = 5

--SAVE THE RACE ID AND CAR ID OF THE SPECIFIED ENTRY
SELECT @race = Races_ID, @car = Cars_ID
FROM dbo.Entries
WHERE ID = @entry

--SELECT THE RACES WITH THE SAME CAR WHERE THE CREW MEMBERS OF THE SPECIFIED ENTRY HAVE PARTICIPATED BEFORE
SELECT cr.ID, cr.contactname, r.ID raceid, r.racename
INTO #Exp
FROM dbo.Contacts cr
INNER JOIN dbo.Crews cs
ON cr.ID = cs.Contacts_ID
INNER JOIN dbo.Entries e
ON cs.Entries_ID = e.ID AND e.Races_ID <= @race AND e.Cars_ID = @car
LEFT OUTER JOIN dbo.Races r
ON e.Races_ID = r.ID
ORDER BY cr.ID, r.ID DESC

--CREATE THE DINAMIC LIST OF COLUMNS (RACE NAMES) WE'RE GOING TO USE IN THE PIVOT
SELECT @races = ISNULL(@races + ',[', '[') + r.racename + ']'
FROM (SELECT DISTINCT raceid, racename FROM #Exp) r
ORDER BY r.raceid DESC

--GENERATE AND EXECUTE THE DYNAMIC QUERY
SET @query = 
'SELECT contactname,' + @races +
'FROM (SELECT ID contact_id, ID, contactname, racename FROM #Exp) p
PIVOT
(COUNT(ID) FOR p.racename IN ( ' + @races + ' )) as pvt
ORDER BY contact_id'
EXEC sys.sp_executesql @query

DROP TABLE #Exp

这将生成一个 table,其中 1 和 0 指定指定条目的机组成员在之前的比赛中。有多少场比赛并不重要,因为动态查询会适应显示所有比赛。

*此查询的结果考虑了与指定条目具有相同汽车的比赛;你举的例子有 Mandy Lifeboats on Old Race 是另一辆车。也许我误解了这个问题或者它真的很令人困惑?