我面临的问题是,我正在寻找一种方法来实现以下目标:
我需要为每个人获得1行,其中的列显示哪些组已链接到此人。我得到了以下3个表
示例数据(脚本):
Create table persons (uniqueid int, email varchar(50))
Create table groups (uniqueid int, title varchar(50))
Create table link (uniqueid int, groupid int, personid int)
insert into persons (uniqueid, email) values (1, 'firstname1.lastname1@domain.com'), (2, 'firstname2.lastname2@domain.com'), (3, 'firstname3.lastname3@domain.com')
insert into groups (uniqueid, title) values (1, 'Servicedesk'), (2, 'SecondLine'), (3, 'ThirdLine')
insert into link (uniqueid, groupid, personid) values (1, 1, 1), (2, 1, 2), (3, 1, 3), (4, 2, 1), (5, 3, 2), (6, 1, 3)
当前查询:
select p.email, g.title
FROM link as l
left join groups g on l.groupid = g.uniqueid
left join persons p on l.personid = p.uniqueid
group by p.email, g.title
输出当前查询:
email title
firstname1.lastname1@domain.com SecondLine
firstname1.lastname1@domain.com Servicedesk
firstname2.lastname2@domain.com Servicedesk
firstname2.lastname2@domain.com ThirdLine
firstname3.lastname3@domain.com Servicedesk
预期的最终结果:
email Group1 Group2 Group3
firstname1.lastname1@domain.com Servicedesk SecondLine NULL
firstname2.lastname2@domain.com Servicedesk NULL NULL
firstname3.lastname3@domain.com Servicedesk NULL NULL
要开始尝试解决这个问题,我尝试使用FOR XML PATH ('')
为每个人创建1行,所有组都在1列中,但这会在我的生产环境中生成错误Column name 'Email Address' contains an invalid XML identifier as required by FOR XML; ' '(0x0020) is the first character at fault.
。
在这一行之后,我想将它们分成列。
目前,我正在寻找正确使用的功能,因此我可以构建完整的查询。
答案 0 :(得分:3)
您可以动态生成列的名称,并在PIVOT
DECLARE @persons TABLE (uniqueid int, email varchar(50))
DECLARE @groups TABLE(uniqueid int, title varchar(50))
DECLARE @link TABLE(uniqueid int, groupid int, personid int)
insert into @persons (uniqueid, email) values (1, 'firstname1.lastname1@domain.com'), (2, 'firstname2.lastname2@domain.com'), (3, 'firstname3.lastname3@domain.com')
insert into @groups (uniqueid, title) values (1, 'Servicedesk'), (2, 'SecondLine'), (3, 'ThirdLine')
insert into @link (uniqueid, groupid, personid) values (1, 1, 1), (2, 1, 2), (3, 1, 3), (4, 2, 1), (5, 3, 2), (6, 1, 3)
SELECT p.*
FROM
(
select p.email
,g.title
,'Group'+CAST(ROW_NUMBER() OVER(PARTITION BY p.email ORDER BY (SELECT NULL)) AS varchar(2)) AS ColumnName
FROM @link as l
left join @groups g on l.groupid = g.uniqueid
left join @persons p on l.personid = p.uniqueid
group by p.email, g.title
) AS tbl
PIVOT
(
MAX(title) FOR ColumnName IN(Group1,Group2,Group3, Group4 /*add as many as you need*/)
) AS p;
结果
email Group1 Group2 Group3 Group4
firstname1.lastname1@domain.com SecondLine Servicedesk NULL NULL
firstname2.lastname2@domain.com Servicedesk ThirdLine NULL NULL
firstname3.lastname3@domain.com Servicedesk NULL NULL NULL