1

私の現在のスキーマは次のようになります。

PersonType (PersonTypeID, Name, Description)

Person (PersonID,PersonTypeID, FirstName, ... )

PersonDynamicField (PersonDynamicFieldID, PersonTypeID, Name, Description, DataType, DefaultValue, ...)

PersonDynamicFieldValue (PersonDynamicFieldValueID, PersonDynamicFieldID, PersonID, Value, ...)

つまり、人は特定のタイプです。たとえば、顧客。ごとPersonTypeに、PersonType について格納する追加フ​​ィールドを動的に追加できます。顧客の場合、LikesChocolate、FavoriteColor、HappinessScale などのフィールドを PersonDynamicField に追加したい場合があります。これらのフィールドの値は、PersonDynamicFieldValue に格納されます。

私の文章が理にかなっていることを願っています。

私がやりたいのは、この構造を平坦化し、次のような結果を返すクエリです。

PersonID, PersonTypeID, FirstName, LikesChocolate, FavoriteColor, HappinessScale
1, 2, Robert, 1, Green, 9
2, 2, John, 0, Orange, 5
...

私はちょっと立ち往生していて、どこから始めればいいのか本当にわかりません.

手伝ってくれますか?

4

2 に答える 2

4

目的の結果を得るために、データの行を列に変換する方法がいくつかあります。

SQL Server 2005 以降では、 PIVOT関数を使用できます。コードの基本構造は次のようになります。

SELECT personid, persontypeid, firstname,[FavoriteColor],[HappinessScale],[LikesChocolate] 
from 
( 
  select p.personid, p.persontypeid, p.firstname, f.name fields, v.value 
  from person p 
  inner join persontype pt 
    on p.persontypeid = pt.persontypeid 
  left join PersonDynamicField f 
    on p.PersonTypeID = f.PersonTypeID 
  left join PersonDynamicFieldValue v 
    on f.PersonDynamicFieldID = v.PersonDynamicFieldID 
    and p.personid = v.personid 
) x 
pivot 
( 
  max(value) 
  for fields in ([FavoriteColor],[HappinessScale],[LikesChocolate]) 
) p;

SQL Fiddle with Demoを参照してください。PIVOT で発生する 1 つの問題は、列に変換される値が実行時に認識されている必要があることです。あなたの状況では、値が変わる可能性があるため、これは不可能に思えます。結果として、動的 SQL を使用して結果を取得する必要があります。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Name) 
                    from PersonDynamicField
                    where PersonTypeID = 2
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT personid, persontypeid, firstname,' + @cols + ' 
            from 
            (
               select p.personid,
                p.persontypeid,
                p.firstname,
                f.name fields,
                v.value
              from person p
              inner join persontype pt
                on p.persontypeid = pt.persontypeid
              left join PersonDynamicField f
                on p.PersonTypeID = f.PersonTypeID
              left join PersonDynamicFieldValue v
                on f.PersonDynamicFieldID = v.PersonDynamicFieldID
                and p.personid = v.personid
            ) x
            pivot 
            (
                max(value)
                for fields in (' + @cols + ')
            ) p '


execute(@query);

SQL Fiddle with Demoを参照してください。これらは結果を与えます:

| PERSONID | PERSONTYPEID | FIRSTNAME | FAVORITECOLOR | HAPPINESSSCALE | LIKESCHOCOLATE |
-----------------------------------------------------------------------------------------
|        1 |            2 |    Robert |         Green |              9 |              1 |
|        2 |            2 |      John |        Orange |              5 |              0 |
于 2013-07-09T23:41:47.993 に答える
-2

必要なものは一般にピボットと呼ばれ、SQL Server には役立つ操作があります。例については、MSDN のこの記事をご覧ください: http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

于 2013-07-09T23:32:57.783 に答える