1

我当前的架构如下所示:

PersonType (PersonTypeID, Name, Description)

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

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

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

也就是说,一个人属于某种类型。例如,客户。对于每个PersonType,都可以动态添加额外的字段来存储关于 PersonType 的信息。对于客户,我们可能希望将字段添加到 PersonDynamicField,例如 LikesChocolate、FavoriteColor、HappinessScale 等。然后这些字段的值将存储在 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 将遇到的一个问题是,它要求转换为列的值在运行时是已知的。对于您的情况,这似乎是不可能的,因为值可能会改变。因此,您将不得不使用动态 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 回答