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     

私はSQLServer2008を使用していますが、一般的なソリューションがいいでしょう。

4

2 に答える 2

3

使用している RDBMS を指定していませんが、これはピボットです。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 を参照してください

3 つすべてで同じ結果が得られます。

| PROPERTY |  BOB |  FRED |
---------------------------
|     Eyes | Blue |       |
|     Hair |  Red | Brown |
|   Height |      |  Tall |
于 2013-01-16T19:59:35.423 に答える
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 によっては、代わりにピボット クエリを使用できる場合があります。これにより、構文が簡素化されます (人数や名前が不明な場合は可能になります)。

于 2013-01-16T19:53:25.720 に答える