SQL Server将相关表中的行转换为动态列

SQL Server将相关表中的行转换为动态列,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我无法将行转换为动态列,我有以下结构: 用户表默认值 UserRegion关系:用户 区域语言 我的难点是根据RegionLanguage表的返回创建动态列的结构。 我的Where子句是RegionLanguage.LanguageID=1,如果用户和region表UserRegion之间存在关系,则RegionLanguage.RegionName的大小写为“是” 期望输出为: 我正在使用SQL Server 2008。这里有几个选项。根据您的要求,您可以执行以下操作: 多次加入区域表。如果您

我无法将行转换为动态列,我有以下结构:

用户表默认值 UserRegion关系:用户 区域语言 我的难点是根据RegionLanguage表的返回创建动态列的结构。 我的Where子句是RegionLanguage.LanguageID=1,如果用户和region表UserRegion之间存在关系,则RegionLanguage.RegionName的大小写为“是”

期望输出为:
我正在使用SQL Server 2008。

这里有几个选项。根据您的要求,您可以执行以下操作:

多次加入区域表。如果您只有4个左右可能的列,这是很好的。然后用一些案例逻辑总结数据。这可能是最简单的方法,但可能缺少您需要的功能,或者不足以满足可能导致大量复制粘贴的注释量

支点。一旦你掌握了窍门,这真的很好,但一开始就有点让人望而生畏。查阅一些示例并熟悉PIVOT命令,您就可以理解它了。有更多的功能,不会让你进入复制过去的戏剧

多个子查询。你可能不想这样,但这是可能的

动态SQL。比上一个更糟糕,因为有一个替代方案,你无论如何都应该使用它。只是为了答案的完整性而列出它

以下是此场景的一个简单轴心示例:

select name
    , max(case when [Region Name 1] is null then 0 else 1 end) [Region Name 1]
    , max(case when [Region Name 2] is null then 0 else 1 end) [Region Name 2]
    , max(case when [Region Name 3] is null then 0 else 1 end) [Region Name 3]
    , max(case when [Region Name 4] is null then 0 else 1 end) [Region Name 4]
    , max(case when [Region Name 5] is null then 0 else 1 end) [Region Name 5]
    , max(case when [Region Name 6] is null then 0 else 1 end) [Region Name 6]

from 
(select [user].name, RegionName, RegionName r2 from (values 
    (1,'First User Name'),
    (2, 'Second User Name')) [user](id, name)
left join (values
    (1, 1),
    (1, 3),
    (1, 3),
    (2, 4),
    (2, 1),
    (2, 6))
UserRegion(UserID,  RegionID)
    on [user].id = UserRegion.UserID
left join (values
    (1 ,1, 'Region Name 1'),
    (2 ,1, 'Region Name 2'),
    (3 ,1, 'Region Name 3'),
    (4 ,1, 'Region Name 4'),
    (5 ,2, 'Region Name 5'),
    (6 ,3, 'Region Name 6'))
RegionLanguage(RegionID, LanguageID, RegionName)
    on UserRegion.RegionID = RegionLanguage.RegionID) sub

PIVOT
(
MAX(RegionName)
FOR RegionName IN ( [Region Name 1]
    , [Region Name 2]
    , [Region Name 3]
    , [Region Name 4]
    , [Region Name 5]
    , [Region Name 6]   )
) AS PivotTable
group by name

使用SQL Server PIVOT函数@Ondipuli很好的指示,谢谢!你的回答很透彻,解释性很强。在发布问题之前,我看到了许多使用PIVOT的选项。但我不太明白如何应用,因为我发现了一些具有多个动态列的内容。我有无数列的可能性,因为它们来自我在表格区域语言中的选择。。。请给我举一个适用的例子好吗?我考虑从我的web应用程序发送一个就绪查询,在查询之前创建查询区域并合并到最终查询中。但这将是一个糟糕的解决方案。 UserID RegionID 1 1 1 2 1 3 2 1 2 2 2 3 RegionID LanguageID RegionName 1 1 Region Name 1 2 1 Region Name 2 3 1 Region Name 3 4 1 Region Name 4 5 2 Region Name 5 6 3 Region Name 6 UserID UserName Region Name 1 Region Name 2 Region Name 3 Region Name 4 1 First User Name Yes Yes Yes No 2 Second User Name Yes Yes Yes No
select name
    , max(case when [Region Name 1] is null then 0 else 1 end) [Region Name 1]
    , max(case when [Region Name 2] is null then 0 else 1 end) [Region Name 2]
    , max(case when [Region Name 3] is null then 0 else 1 end) [Region Name 3]
    , max(case when [Region Name 4] is null then 0 else 1 end) [Region Name 4]
    , max(case when [Region Name 5] is null then 0 else 1 end) [Region Name 5]
    , max(case when [Region Name 6] is null then 0 else 1 end) [Region Name 6]

from 
(select [user].name, RegionName, RegionName r2 from (values 
    (1,'First User Name'),
    (2, 'Second User Name')) [user](id, name)
left join (values
    (1, 1),
    (1, 3),
    (1, 3),
    (2, 4),
    (2, 1),
    (2, 6))
UserRegion(UserID,  RegionID)
    on [user].id = UserRegion.UserID
left join (values
    (1 ,1, 'Region Name 1'),
    (2 ,1, 'Region Name 2'),
    (3 ,1, 'Region Name 3'),
    (4 ,1, 'Region Name 4'),
    (5 ,2, 'Region Name 5'),
    (6 ,3, 'Region Name 6'))
RegionLanguage(RegionID, LanguageID, RegionName)
    on UserRegion.RegionID = RegionLanguage.RegionID) sub

PIVOT
(
MAX(RegionName)
FOR RegionName IN ( [Region Name 1]
    , [Region Name 2]
    , [Region Name 3]
    , [Region Name 4]
    , [Region Name 5]
    , [Region Name 6]   )
) AS PivotTable
group by name