鉴于此数据:
Name Property Value
---------- ---------- ----------
Bob Hair Red
Bob Eyes Blue
Fred Hair Brown
Fred Height Tall
生成这些结果需要什么SQL?
Property Bob Fred
---------- ---------- ----------
Hair Red Brown
Eyes Blue
Height Tall
我使用的是SQL Server 2008,但通用解决方案会很好。
答案 0 :(得分:3)
您没有指定您正在使用的RDBMS,但这是 pivot 。您可以在所有数据库中使用聚合函数和CASE
表达式:
select property,
max(case when name='Bob' then value else '' end) Bob,
max(case when name='Fred' then value else '' end) Fred
from yourtable
group by property
如果您使用的是具有PIVOT
功能的数据库(SQL Server 2005 + / Oracle 11g +),那么您的代码将与此类似:
select *
from
(
select property, name, value
from yourtable
) src
pivot
(
max(value)
for name in (Bob, Fred)
) piv
如果您提前知道名称值,则上述查询效果很好,但如果您不知道,那么您将需要使用动态sql:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT property,' + @cols + ' from
(
select property, name, value
from yourtable
) x
pivot
(
max(value)
for name in (' + @cols + ')
) p '
execute(@query)
这三个都会产生相同的结果:
| PROPERTY | BOB | FRED |
---------------------------
| Eyes | Blue | |
| Hair | Red | Brown |
| Height | | Tall |
答案 1 :(得分:1)
这是老式的方式,当然假设每个(名称,属性)都是唯一的:
SELECT Properties.Property, Bob.Value, Fred.Value
FROM
(
SELECT DISTINCT Property
FROM myTable
) Properties
LEFT OUTER JOIN
(
SELECT Property, Value
FROM myTable
WHERE Name = 'Bob'
) Bob ON Properties.Property = Bob.Property
LEFT OUTER JOIN
(
SELECT Property, Value
FROM myTable
WHERE Name = 'Fred'
) Fred ON Properties.Property = Fred.Property
当然,如果您事先知道列,则只能执行此操作。如果不这样做,你可以创建并执行动态SQL,但这并非没有问题。
根据您的RDBMS,您可以使用数据透视查询,这将简化语法(或者如果您的人数未知/人名,则可以使用)