2

我想知道是否可以在 SQL Server 2012 中完成以下操作。

我有以下数据:

Product_ID    Date     Attribute    Value
-------------------------------------------
10025135       2009    Colour       Red
10025135       2009    Size         20 cm
10025135       2009    Material     Steel
10025135       2010    Colour       Green
10025135       2010    Size         NULL
10025135       2010    Material     Alloy
10025136       2009    Colour       Black
10025136       2009    Size         30cm
10025136       2009    Material     NULL

我想检索数据,以便它们显示如下:

Product_ID    Date    Colour    Size     Material
-------------------------------------------------
10025135       2009   Red       20 cm    Steel
10025135       2010   Green     NULL     Alloy
10025136       2009   Black     30 cm    NULL

我试图改变它们但没有成功。

4

2 回答 2

4
SELECT   Product_ID, Date, Colour, Size, Material
FROM
        (
            SELECT  Product_ID, Date, Attribute, Value
            FROM    Table1
        ) org
        PIVOT
        (
            MAX(Value)
            FOR Attribute IN (Colour, Size, Material)
        ) pivotHeader

输出

╔════════════╦══════╦════════╦════════╦══════════╗
║ PRODUCT_ID ║ DATE ║ COLOUR ║  SIZE  ║ MATERIAL ║
╠════════════╬══════╬════════╬════════╬══════════╣
║   10025135 ║ 2009 ║ Red    ║ 20 cm  ║ Steel    ║
║   10025135 ║ 2010 ║ Green  ║ (null) ║ Alloy    ║
║   10025136 ║ 2009 ║ Black  ║ 30cm   ║ (null)   ║
╚════════════╩══════╩════════╩════════╩══════════╝

另一种方法是使用MAX()andCASE

SELECT  Product_ID, DATE,
        MAX(CASE WHEN Attribute = 'Colour' THEN Value END ) Colour,
        MAX(CASE WHEN Attribute = 'Size' THEN Value END ) Size,
        MAX(CASE WHEN Attribute = 'Material' THEN Value END ) Material
FROM    Table1
GROUP   BY Product_ID, DATE
于 2013-03-13T03:09:52.737 回答
1

您可以实现使用该PIVOT函数来获得所需的结果。这将获取列中的行值attribute并将它们转换为列。

执行此操作时要考虑的主要事项是您是否将拥有已知或未知数量的attribute值。

如果这些值是提前知道的,那么您可以使用 static 对这些值进行硬编码PIVOT

select product_id,
  Colour,
  Size,
  Material
from 
(
  select product_id, date, attribute, value
  from yourtable
) src
pivot
(
  max(value)
  for attribute in (Colour, Size, Material)
) piv;

请参阅SQL Fiddle with Demo

但是如果attribute列的值是未知的或需要动态的,那么您将需要实现动态 SQL。动态 SQL 将获取要在 SQL 字符串中使用的列的列表。

获取列列表的代码类似于:

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(attribute) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

这个查询的结果是:

[Colour],[Material],[Size] 

这会在执行时创建attributes应转换为列的列表,并将其连接到执行的最终字符串中。您的动态 SQL 数据透视代码是:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(attribute) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT product_id,' + @cols + ' 
             from 
             (
                select product_id, date, attribute, value
                from yourtable
             ) x
             pivot 
             (
                max(value)
                for attribute in (' + @cols + ')
             ) p '

execute(@query)

请参阅SQL Fiddle with Demo

两个查询的结果是:

| PRODUCT_ID | COLOUR |   SIZE | MATERIAL |
-------------------------------------------
|   10025135 |    Red |  20 cm |    Steel |
|   10025136 |  Black |   30cm |   (null) |
|   10025135 |  Green | (null) |    Alloy |
于 2013-03-13T10:54:29.943 回答