我当前的架构如下所示:
PersonType (PersonTypeID, Name, Description)
Person (PersonID,PersonTypeID, FirstName, ... )
PersonDynamicField (PersonDynamicFieldID, PersonTypeID, Name, Description, DataType, DefaultValue, ...)
PersonDynamicFieldValue (PersonDynamicFieldValueID, PersonDynamicFieldID, PersonID, Value, ...)
也就是说,一个人属于某种类型。例如,客户。对于每个PersonType
,可以动态添加其他字段来存储有关PersonType的内容。对于Customer,我们可能希望向PersonDynamicField添加字段,例如LikesChocolate,FavoriteColor,HappinessScale等。这些字段的值将存储在PersonDynamicFieldValue中。
我希望我的写作有道理。
我想做的是一个可以展平此结构并返回如下结果的查询:
PersonID, PersonTypeID, FirstName, LikesChocolate, FavoriteColor, HappinessScale
1, 2, Robert, 1, Green, 9
2, 2, John, 0, Orange, 5
...
我有点被困,甚至不知道从哪里开始。
你能帮忙吗?
答案 0 :(得分: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 |
答案 1 :(得分:-2)
您想要的通常称为数据透视,SQL Server的操作可能有所帮助。请查看MSDN上的这篇文章,例如:http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx