我有一个表,它链接到另一个表,指定键值对的值。然后,Value表链接到一个包含名称(key)的表。表定义(足够接近)如下:
---------------
Entity
---------------
EntityID
Name
Some other data
---------------
Value
----------------
ValueID
EntityID
Value
---------------
Key
---------------
KeyID
ValueID
Name
每个实体可以有多个值,每个值都有一个键。每个实体可能没有相同数量的值。基本上,这种结构允许我动态添加表行,而无需修改Entity表。
我想在Entity表上执行select *,使用Key.Name字段作为列标题,并显示相应的Value.Values
SQL中是否有可用的动态结构,我可以为实体中的每一行插入,然后返回一个选择?
我希望这是有道理的!
答案 0 :(得分:5)
根据您的说明,听起来您想要PIVOT
数据。有两种方法可以使用PIVOT执行此操作,可以使用静态数据透视表来编码要转换的列,也可以使用动态数据透视表来确定执行时的列。
Static Pivot:
select *
from
(
select e.entityid, v.value,
e.name EntityName, k.name KeyName
from value v
left join entity e
on v.entityid = e.entityid
left join [key] k
on v.valueid = k.valueid
) x
pivot
(
max(value)
for KeyName in ([name 1], [name 2], [name 3], [name 4], [name 5])
) p;
Dynamic Pivot在运行时确定列:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name)
from [key]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT entityid, EntityName, ' + @cols + ' from
(
select e.entityid, v.value,
e.name EntityName, k.name KeyName
from value v
left join entity e
on v.entityid = e.entityid
left join [key] k
on v.valueid = k.valueid
) x
pivot
(
max(value)
for KeyName in (' + @cols + ')
) p '
execute(@query)
这两个都可以放在存储过程中。如果您为每个表发布一些示例数据,然后发布所需的结果,则可以更轻松地确定正确的查询。