我想知道是否可以在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
我试图让它们无法成功。
答案 0 :(得分: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()
和CASE
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
答案 1 :(得分:1)
您可以使用PIVOT
功能来实现所需的结果。这将获取attribute
列中的行值并将其转换为列。
执行此操作时要考虑的主要事项是您是否具有已知或未知数量的attribute
值。
如果提前知道这些值,那么您可以使用静态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;
但是如果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)
两个查询的结果是:
| PRODUCT_ID | COLOUR | SIZE | MATERIAL |
-------------------------------------------
| 10025135 | Red | 20 cm | Steel |
| 10025136 | Black | 30cm | (null) |
| 10025135 | Green | (null) | Alloy |