如何使用 PIVOT 在 SQL 查询中生成数据驱动列

How to generate data driven columns in a SQL query using PIVOT

我正在尝试了解如何在 SQL 中使用 PIVOT。理想情况下,我想要一个包含动态行和动态列的查询。我会 post 到目前为止我得到的代码示例,但恐怕我没有任何工作。

我有 2 个主要实体和一个这样的 M:N 地图。

DECLARE @people TABLE(id INT NOT NULL PRIMARY KEY IDENTITY(1,1),name VARCHAR(MAX) NOT NULL)
INSERT INTO @people (name) VALUES ('Joe'),('Sally'),('Mary')

DECLARE @group TABLE(id INT NOT NULL PRIMARY KEY IDENTITY(1,1),name VARCHAR(MAX) NOT NULL)
INSERT INTO @group (name) VALUES ('Cool Kids'),('Band Camp'),('Chess Club')

DECLARE @map TABLE(peopleId INT, groupId INT)
INSERT INTO @map (peopleId,groupId) VALUES (1,1),(1,3),(2,3),(3,2)

理想情况下,我想要一个结果,将一个实体作为行,将另一个实体作为列,并在交集处放置一些数据(简单的布尔值或求和)。

       Cool Kids  Band Camp   Chess Club
Joe    TRUE       FALSE       TRUE
Sally  FALSE      FALSE       TRUE
Mary   FALSE      TRUE        TRUE

我见过的大多数示例似乎都建议您需要提前知道要查询哪些@groups,而我不知道。

这可能每天都会被问几次,答案总是动态的。

DECLARE @sql VARCHAR(MAX),
        @cols VARCHAR(MAX)

-- define the columns that will be dynamic
SELECT @cols = COALESCE(@cols + ',', '') + QUOTENAME(name)
FROM [group] g

-- build the sql and insert the dynamic column names in your pivot statement
SET @sql = '
    SELECT *
    FROM (
        SELECT  p.name personName, g.name groupName
        FROM  people p 
        LEFT JOIN map m on p.id = m.peopleId
        LEFT JOIN [group] g on m.groupId = g.id
    ) t
    PIVOT 
    (
        COUNT(groupName)
        FOR groupName IN (' + @cols + ')
    ) p
'
EXEC(@sql)

DEMO