SQL返回值作为基于键和值类型表的字段 - PIVOT,CASE等?

时间:2011-08-04 14:06:23

标签: sql sql-server-2005 pivot

使用SQL Server 2005我有以下表格:

值:

ValueID  UserID    ValueTypeID  ValueKey  Text  Number
------------------------------------------------------
1        345       1            NAME      Bob   NULL
2        345       2            AGE       NULL  30
3        689       1            NAME      Sam   NULL
4        689       2            AGE       NULL  45

值类型:

ValueTypeID  CodeName
---------------------
1            TEXT
2            NUMBER

我希望得到如下结果:

UserID  Name  Age
-----------------
345     Bob   30
689     Sam   45

我确信这是可能的,使用一个数据透视表,也许是一些案例陈述?还有更多的ValueKeys,甚至更多的ValueTypes,但这将让我前进。我事先知道ValueKeys的列表,所以这应该意味着我可以避免动态查询。

3 个答案:

答案 0 :(得分:1)

经典的透视查询。然后,如果需要,可以使用ValueTypeID:

SELECT UserID, 
       MAX(
           CASE WHEN ValueKey = 'NAME' 
                THEN 
                    CASE WHEN ValueTypeID = 1 
                             THEN Text 
                         WHEN ValueTypeID = 2
                             THEN Number 
                         WHEN ValueTypeID = 3
                             THEN Date
                         ELSE NULL
                    END
                ELSE NULL 
           END
       ) AS Name,
       MAX(
           CASE WHEN ValueKey = 'AGE' 
                THEN 
                    CASE WHEN ValueTypeID = 1 
                             THEN Text 
                         WHEN ValueTypeID = 2
                             THEN Number 
                         WHEN ValueTypeID = 3
                             THEN Date
                         ELSE NULL
                    END
                ELSE NULL 
           END
       ) AS Age,
       MAX(
           CASE WHEN ValueKey = 'DATEBIRTH' 
                THEN 
                    CASE WHEN ValueTypeID = 1 
                             THEN Text 
                         WHEN ValueTypeID = 2
                             THEN Number 
                         WHEN ValueTypeID = 3
                             THEN Date
                         ELSE NULL
                    END
                ELSE NULL 
           END
       ) AS DateBirth
FROM Value
GROUP BY UserID

但它可能没用,你可以用较少的代码来减少通用性:

SELECT UserID, 
       MAX(
           CASE WHEN ValueKey = 'NAME' 
                THEN Text -- I know that name is a string
                ELSE NULL 
           END
       ) AS Name,
       MAX(
           CASE WHEN ValueKey = 'AGE' 
                THEN Number -- I know that age is a number
                ELSE NULL 
           END
       ) AS Age,
       MAX(
           CASE WHEN ValueKey = 'DATEBIRTH' 
                THEN Date -- I know that date of birth is a date
                ELSE NULL 
           END
       ) AS DateBirth
FROM Value
GROUP BY UserID

答案 1 :(得分:0)

决议应该是重新设计表格。 valueType查找在实现时完全没用。您应该只有一个“ValueText”列而不是“Text”,“Number”,...并将所有值存储在该1列中。然后它将是一个简单的join语句。

答案 2 :(得分:0)

您可以按UserID分组并使用子查询来获取字段值。

declare @T table
(
  ValueID int,
  UserID int,
  ValueTypeID int,
  ValueKey varchar(10),
  Text varchar(10),
  Number int
)

insert into @T values
(1,        345,       1,            'NAME',      'Bob',   NULL),
(2,        345,       2,            'AGE',       NULL,    30),
(3,        689,       1,            'NAME',      'Sam',   NULL),
(4,        689,       2,            'AGE',       NULL,    45)

select T1.UserID,
       (select [Text]
        from @T as T2
        where T1.UserID = T2.UserID and
              T2.ValueKey = 'NAME') as Name,
       (select Number
        from @T as T2
        where T1.UserID = T2.UserID and
              T2.ValueKey = 'AGE') as Age
from @T as T1
group by T1.UserID