我有一个包含3列的大表,如下所示:
Invoice Product Color
1 Pant Red
1 Pant Black
1 Shirt Green
2 Pant White
2 Pant Black
2 Pant Blue
我想在Invoice& amp;产品然后将所有唯一的颜色值显示在相关的分组记录中,如下所示:
Invoice Product Colour1 Colour2 Colour3
1 Pant Red Black
1 Shirt Green
2 Pant White Black Blue
这在SQL Server中是否可行?
答案 0 :(得分:2)
在SQL Server中可以 - 如果您知道有三个颜色列。如果有一个变量号,那么它仍然可以,但它需要动态SQL。
我会使用条件聚合来解决这个问题:
select invoice, product,
max(case when seqnum = 1 then colour end) as colour1,
max(case when seqnum = 2 then colour end) as colour2,
max(case when seqnum = 3 then colour end) as colour3
from (select t.*,
row_number() over (partition by invoice, product order by (select nULL)) as seqnum
from table t
) t
group by invoice, product;
答案 1 :(得分:0)
要将行转换为列,您需要在Pivot
中使用Sql Server
。如果您事先知道列数,则可以静态使用旋转作为 Gordin Linoff 建议的答案。
有时,colors
的数量可能会有所不同(在您的示例中,只有3种颜色)。在这种情况下,您无法对列名进行硬编码。首先,您需要将列名称动态地转换为变量。
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + COLUMNNAME + ']', '[' + COLUMNNAME + ']')
FROM
(
SELECT DISTINCT
'COLOR'+CAST(ROW_NUMBER() OVER(PARTITION BY INVOICE,PRODUCT ORDER BY (SELECT 0)) AS VARCHAR(10)) COLUMNNAME
FROM #TEMP
) PV
ORDER BY COLUMNNAME
现在,上面的变量的列值为Comma Separated Values
,可以与IN
运算符动态地用于以下查询。由于您的表格没有COLOR1
,COLOR2
等值,因此我提供了使用PARTITION BY获取每个INVOICE
及其PRODUCT
的列名的逻辑子句。
DECLARE @query NVARCHAR(MAX)
SET @query = '-- This outer query forms your pivoted result
SELECT * FROM
(
-- Source data for pivoting
SELECT DISTINCT INVOICE,PRODUCT,COLOR,
''COLOR''+CAST(ROW_NUMBER() OVER(PARTITION BY INVOICE,PRODUCT ORDER BY (SELECT 0)) AS VARCHAR(10)) COLUMNNAME
FROM #TEMP
) x
PIVOT
(
--Defines the values in each dynamic columns
MIN(COLOR)
-- Get the names from the @cols variable to show as column
FOR COLUMNNAME IN (' + @cols + ')
) p
ORDER BY INVOICE;'
EXEC SP_EXECUTESQL @query