SQL存储动态数据

时间:2012-10-09 13:11:06

标签: sql sql-server sql-server-2008 stored-procedures pivot

我有一个表,它链接到另一个表,指定键值对的值。然后,Value表链接到一个包含名称(key)的表。表定义(足够接近)如下:

---------------
Entity
---------------
EntityID
Name
Some other data

---------------
Value
----------------
ValueID
EntityID
Value

---------------
Key
---------------
KeyID
ValueID
Name

每个实体可以有多个值,每个值都有一个键。每个实体可能没有相同数量的值。基本上,这种结构允许我动态添加表行,而无需修改Entity表。

我想在Entity表上执行select *,使用Key.Name字段作为列标题,并显示相应的Value.Values

SQL中是否有可用的动态结构,我可以为实体中的每一行插入,然后返回一个选择?

我希望这是有道理的!

1 个答案:

答案 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;

请参阅SQL Fiddle With Demo

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)

请参阅SQL Fiddle With Demo

这两个都可以放在存储过程中。如果您为每个表发布一些示例数据,然后发布所需的结果,则可以更轻松地确定正确的查询。