将三行值转换为列,而不是逗号分隔值

Posted

技术标签:

【中文标题】将三行值转换为列,而不是逗号分隔值【英文标题】:Convert three rows values into columns, NOT as comma separated value 【发布时间】:2020-11-05 09:03:40 【问题描述】:

我有类似的表结构

select catalog_item_id,metal_type,metal_color 
from catalog_item_castings 
where catalog_Item_Id =465173

它返回输出为:

我希望输出为:

我想将此数据插入到 SQL Server 中的新临时表中。

提前致谢。

【问题讨论】:

铸件的数量是否始终相同(3)? 你需要考虑旋转。 嗨@Sander,不,铸件的数量并不总是相同。他们可以不同。 【参考方案1】:

条件聚合是一个选项:

SELECT
   catalog_item_id,
   MAX(CASE WHEN rn % 3 = 1 THEN CONCAT(metal_type, '/', metal_color) END) AS Casting_1,
   MAX(CASE WHEN rn % 3 = 2 THEN CONCAT(metal_type, '/', metal_color) END) AS Casting_2,
   MAX(CASE WHEN rn % 3 = 0 THEN CONCAT(metal_type, '/', metal_color) END) AS Casting_3
FROM (
   SELECT 
      catalog_item_id, metal_type, metal_color, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn
   FROM (VALUES
      (465173, 'na', 'METALCOLOR'),
      (465173, 'na', 'METAL-001'),
      (465173, 'na', 'na')
   ) catalog_item_castings (catalog_item_id, metal_type, metal_color) 
   WHERE catalog_Item_Id = 465173
) t   
GROUP BY catalog_item_id
-- or if you have more than three rows per [catalog_item_id]
-- GROUP BY catalog_item_id, (rn - 1) / 3 

结果:

catalog_item_id Casting_1     Casting_2    Casting_3
-------------------------------------------------
465173          na/METALCOLOR na/METAL-001 na/na

【讨论】:

嗨@Zhorov,谢谢,但值 'na' 和 'METAL COLOR' 。 . . .不固定。 @Dev,比你需要动态旋转,但为什么问题是Convert three rows values into columns, ...【参考方案2】:

您可以在 Dynamic Pivot 语句中使用条件聚合来包含 [metal_type][metal_color] 列的所有不同组合,甚至将来会插入不同的组合值:

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

SELECT @cols = (SELECT STRING_AGG(CONCAT('MAX(CASE WHEN [dr]=',dr,
                                         ' THEN CONCAT([metal_type],''/'',[metal_color]) END) AS [Casting_',dr,']'),',') 
                           WITHIN GROUP ( ORDER BY dr )
                  FROM 
                  ( 
                   SELECT DISTINCT 
                          DENSE_RANK() OVER 
                          (PARTITION BY [catalog_item_id]
                               ORDER BY CONCAT([metal_type],[metal_color])) AS dr
                     FROM [catalog_item_castings] ) c);

SET  @query = 
 'SELECT [catalog_item_id],'+ @cols + 
 ' FROM 
  (
   SELECT *, DENSE_RANK() OVER 
           ( PARTITION BY [catalog_item_id] 
                 ORDER BY CONCAT([metal_type], [metal_color]) ) AS dr
     FROM [catalog_item_castings]
  ) c
 GROUP BY [catalog_item_id]';

EXEC sp_executesql @query; 

Demo

【讨论】:

以上是关于将三行值转换为列,而不是逗号分隔值的主要内容,如果未能解决你的问题,请参考以下文章

将逗号分隔值转换为双引号逗号分隔字符串

Oracle SQL:为列中的每个值创建一个新行,其中更多值用逗号分隔

通过 http 管道将逗号分隔的值转换为 list<string>

将长值列表转换为逗号分隔以及每个值周围的括号

将多行转换为雪花中的一个逗号分隔值

如何将数字转换为 Klaviyo 中的逗号分隔值