SQL Server:每行最多几列的列名

时间:2016-03-31 03:39:36

标签: sql-server tsql max ssms

我有一个名为campaigns的表格,其中显示了每个类别在电子邮件广告系列中显示的“图块”数量,如下所示

    campaign_id     categoryA_tiles   categoryB_tiles   categoryC_tiles ... cateogory Z_tiles
        1               5                7                    4         ...      4
        2               4                4                    9         ...      1

我需要在此表中添加3列,以显示每个电子邮件广告系列的3个最常出现的类别(即列名称)。例如,我希望结果看起来像这样

campaign_id ...  category_1    category_2    category_3
    1       ...   categoryB    categoryA     categoryZ
    2       ...   categoryC    categoryA     categoryB

请注意,第二行可能存在关联,在这种情况下,我希望它们从左到右显示。

这与this question基本相同,但我使用的是SSMS 2012而不是MySQl。 This answer是我所追求的,但它与SSMS不兼容。具体而言,我无法解决的错误是如何定义和使用@rownum

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

SQL Server与其他语法之间的语法不一样(特别是对于行号 - 请参阅ROW_NUMBER的文档)。

试试这个:

DECLARE @campaigns TABLE (campaign_id int, categoryA_tiles int, categoryB_tiles int,  categoryC_tiles int, categoryZ_tiles int)

INSERT INTO @campaigns VALUES
(1,5,7,4,4),
(2,4,4,9,1),
(3,2,5,9,10),
(4,1,8,9,11)

SELECT
  t2.campaign_id,
  max(case when t2.RowNumber=1 then t2.name end) as 'highest value',
  max(case when t2.RowNumber=2 then t2.name end) as '2nd highest value',
  max(case when t2.RowNumber=3 then t2.name end) as '3rd highest value',
  max(case when t2.RowNumber=4 then t2.name end) as '4th highest value'
FROM 
    (SELECT campaign_id, name, amt,  ROW_NUMBER() OVER (PARTITION BY campaign_id ORDER BY amt DESC) AS RowNumber 
      FROM 
        (SELECT campaign_id, categoryA_tiles AS amt, 'categoryA_tiles' AS name FROM @campaigns UNION 
         SELECT campaign_id, categoryB_tiles AS amt, 'categoryB_tiles' AS name FROM @campaigns UNION
         SELECT campaign_id, categoryC_tiles AS amt, 'categoryC_tiles' AS name FROM @campaigns UNION
         SELECT campaign_id, categoryZ_tiles AS amt, 'categoryZ_tiles' AS name FROM @campaigns) t1) t2 
GROUP BY t2.campaign_id

答案是:

campaign_id    highest value       2nd highest value    3rd highest value   4th highest value
    1          categoryB_tiles     categoryA_tiles      categoryC_tiles     categoryZ_tiles
    2          categoryC_tiles     categoryA_tiles      categoryB_tiles     categoryZ_tiles
    3          categoryZ_tiles     categoryC_tiles      categoryB_tiles     categoryA_tiles
    4          categoryZ_tiles     categoryC_tiles      categoryB_tiles     categoryA_tiles

答案 1 :(得分:1)

您好,您可以使用UNPIVOT解决此问题,请尝试以下脚本

DECLARE @campaigns TABLE (campaign_id int, categoryA_tiles int, categoryB_tiles int,  categoryC_tiles int, categoryZ_tiles int)

INSERT INTO @campaigns VALUES (1,5,7,4,4),(2,4,4,9,1)

SELECT T.campaign_id,
        MAX((CASE WHEN RowNumber=1 THEN [tVal] END)) AS Category1,
        MAX((CASE WHEN RowNumber=2 THEN [tVal] END)) AS Category2,
        MAX((CASE WHEN RowNumber=3 THEN [tVal] END)) AS Category3
FROM    (
    SELECT campaign_id,tVal,MaxVal,ROW_NUMBER() OVER (PARTITION BY campaign_id ORDER BY MaxVal DESC) AS RowNumber
    FROM @campaigns t1
    UNPIVOT ( MaxVal FOR tVal IN ( categoryA_tiles, categoryB_tiles, categoryC_tiles ,categoryZ_tiles) ) AS u
)   T
GROUP BY T.campaign_id

在这里,您可以根据需要添加/删除更多列/类别(或者可以加入表格 - 广告系列或其他表格 - 用于其他列)。

结果:

campaign_id Category1       Category2       Category3
1           categoryB_tiles categoryA_tiles categoryC_tiles
2           categoryC_tiles categoryA_tiles categoryB_tiles