1

鉴于此数据:

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,但一个通用的解决方案会很好。

4

2 回答 2

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

请参阅带有演示的 SQL Fiddle

如果您使用的是具有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 Fiddle

如果您提前知道名称值,则上述查询效果很好,但如果您不知道,那么您将需要使用动态 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)

请参阅带有演示的 SQL Fiddle

这三个都将产生相同的结果:

| PROPERTY |  BOB |  FRED |
---------------------------
|     Eyes | Blue |       |
|     Hair |  Red | Brown |
|   Height |      |  Tall |
于 2013-01-16T19:59:35.423 回答
1

这是老式的方法,当然假设每个 (Name, Property) 都是唯一的:

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,您可以改用数据透视查询,这将简化语法(或者如果您有未知人数/姓名的人,则可以使用)

于 2013-01-16T19:53:25.720 回答