T:SQL:从行中选择值作为列
Posted
技术标签:
【中文标题】T:SQL:从行中选择值作为列【英文标题】:T:SQL: select values from rows as columns 【发布时间】:2012-10-17 16:11:29 【问题描述】:我有一个 Profiles 表格,以行样式存储配置文件属性值,例如:
[ProfileID] [PropertyDefinitionID] [PropertyValue]
1 6 Jone
1 7 Smith
1 8 Mr
1 3 50000
还有另一个属性定义表:
[PropertyDefinitionID] [PropertyName]
6 FirstName
7 LastName
8 Prefix
3 Salary
如何使用PIVOT
或任何其他方式以这种方式显示它:
[ProfileID] [FirstName] [LastName] [Salary]
1 Jone Smith 5000
【问题讨论】:
【参考方案1】:不用PIVOT
关键字很容易做到这一点,只需分组
select
P.ProfileID,
min(case when PD.PropertyName = 'FirstName' then P.PropertyValue else null end) as FirstName,
min(case when PD.PropertyName = 'LastName' then P.PropertyValue else null end) as LastName,
min(case when PD.PropertyName = 'Salary' then P.PropertyValue else null end) as Salary
from Profiles as P
left outer join PropertyDefinitions as PD on PD.PropertyDefinitionID = P.PropertyDefinitionID
group by P.ProfileID
您也可以使用 PIVOT
关键字来做到这一点
select
*
from
(
select P.ProfileID, P.PropertyValue, PD.PropertyName
from Profiles as P
left outer join PropertyDefinitions as PD on PD.PropertyDefinitionID = P.PropertyDefinitionID
) as P
pivot
(
min(P.PropertyValue)
for P.PropertyName in ([FirstName], [LastName], [Salary])
) as PIV
更新:关于属性的动态数量 - 查看Increment value in SQL SELECT statement
【讨论】:
感谢您的贡献,这两种方法都解决了这个问题,但是如果我们考虑性能,哪一种更快?【参考方案2】:您可能需要将未知数量的PropertyName's
转换为列。如果是这种情况,那么您可以使用动态 sql 来生成结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(PropertyName)
from propertydefinitions
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT profileid, ' + @cols + ' from
(
select p.profileid,
p.propertyvalue,
d.propertyname
from profiles p
left join propertydefinitions d
on p.PropertyDefinitionID = d.PropertyDefinitionID
) x
pivot
(
max(propertyvalue)
for propertyname in (' + @cols + ')
) p '
execute(@query)
见SQL Fiddle with Demo。
【讨论】:
当您只需要将列连接到变量时,您不需要使用for xml
。当您尝试从表中选择数据时,也可能存在安全问题,例如,用户可以对过程具有权限,但对表没有权限。看看我的答案 - ***.com/questions/13055295/…
@RomanPekar 有多种不同的方式来连接列,这是我选择使用的方法。以上是关于T:SQL:从行中选择值作为列的主要内容,如果未能解决你的问题,请参考以下文章