sql server pivot 2值

时间:2015-07-28 02:37:54

标签: sql-server pivot sql-server-2014-express

我试图将2个值合并为一行。

示例数据:

recipeID    componentID count
9           21          5
12          3           1
12          30          1
12          34          1
12          96          1
27          29          1
27          43          1
28          29          1
28          44          1

我尝试了2个枢轴,但我得到了

recipeID   1    2    3    4     11   12   13   14
9          21   NULL NULL NULL  5    NULL NULL NULL
12         NULL NULL NULL 96    NULL NULL NULL 1
12         NULL NULL 34   NULL  NULL NULL 1    NULL
12         NULL 30 NULL   NULL  NULL 1    NULL NULL
12         3    NULL NULL NULL  1    NULL NULL NULL
27         NULL 43 NULL   NULL  NULL 1    NULL NULL
27         29   NULL NULL NULL  1    NULL NULL NULL
28         NULL 44 NULL   NULL  NULL 1    NULL NULL
28         29   NULL NULL NULL  1    NULL NULL NULL 

我希望:

recipeID   1    2    3    4     11   12   13   14
9          21   NULL NULL NULL  5    NULL NULL NULL
12         3    30   34   96    1    1    1    1
27         29   43 NULL   NULL  1    1    NULL NULL
28         29   44 NULL   NULL  1    1    NULL NULL

有什么想法吗?

目前的代码是:

select * from (
SELECT [recipeID]
      ,[componentID]
      ,[count]
      ,ROW_NUMBER() over(partition by [recipeID] order by ComponentID) rn
      ,ROW_NUMBER() over(partition by [recipeID] order by ComponentID)+10 rn10
FROM [Recipe_Ingredients] ri_ ) as ri
PIVOT
(
sum([componentID])
for rn in ([1],[2],[3],[4])) as pvt
PIVOT
(
sum([count])
for rn10 in ([11],[12],[13],[14])) as pvt10

4 个答案:

答案 0 :(得分:1)

这可以做到神奇。

select recipeID, 
  MAX([1]) AS '1', 
  MAX([2]) AS '2',
  MAX([3]) AS '3',
  MAX([4]) AS '4',
  MAX([11]) AS '11',
  MAX([12]) AS '12',
  MAX([13]) AS '13',
  MAX([14]) AS '14'
from (
SELECT [recipeID]
      ,[componentID]
      ,[count]
      ,ROW_NUMBER() over(partition by [recipeID] order by ComponentID) rn
      ,ROW_NUMBER() over(partition by [recipeID] order by ComponentID) + 10 rn10
FROM [Recipe_Ingredients] ri_ ) as ri
PIVOT
(
sum([componentID])
for rn in ([1],[2],[3],[4])) as pvt
PIVOT
(
sum([count])
for rn10 in ([11],[12],[13],[14])) as pvt10
GROUP BY recipeId

这里有Fiddler

希望这有帮助

答案 1 :(得分:1)

另一种方法是将每个枢轴作为子选择,然后将它们组合在一起:

SELECT  Pivot1.recipeID ,
        Pivot1.[1] ,
        Pivot1.[2] ,
        Pivot1.[3] ,
        Pivot1.[4] ,
        Pivot2.[11] ,
        Pivot2.[12] ,
        Pivot2.[13] ,
        Pivot2.[14]
FROM    ( SELECT    *
          FROM      ( SELECT    [recipeID] ,
                                [componentID] ,
                                ROW_NUMBER() OVER ( PARTITION BY [recipeID] ORDER BY componentID ) rn
                      FROM      [Recipe_Ingredients] ri_
                    ) AS ri PIVOT
( SUM([componentID]) FOR rn IN ( [1], [2], [3], [4] ) ) AS pvt
        ) Pivot1
        INNER JOIN ( SELECT *
                     FROM   ( SELECT    [recipeID] ,
                                        [count] ,
                                        ROW_NUMBER() OVER ( PARTITION BY [recipeID] ORDER BY componentID )
                                        + 10 rn10
                              FROM      [Recipe_Ingredients] ri_
                            ) AS ri PIVOT
( SUM([count]) FOR rn10 IN ( [11], [12], [13], [14] ) ) AS pvt10
                   ) Pivot2 ON Pivot2.recipeID = Pivot1.recipeID

发生这种情况是因为PIVOT函数可以处理被旋转的表中的所有字段。我用blog post here中的一个例子解释了这一点。

答案 2 :(得分:0)

像往常一样对外部查询中的列和PRIMARY KEY使用聚合函数(sum或max):

PRIMARY KEY(refer, reg_date, uptime)

Sample SQL Fiddle并且结果:

group by

答案 3 :(得分:0)

以下是使用动态交叉表的另一种解决方案:

SQL Fiddle

DECLARE @sql1 VARCHAR(2000) = '',
        @sql2 VARCHAR(2000) = '',
        @sql3 VARCHAR(2000) = ''

SELECT @sql1 = 
'SELECT
    recipeID' + CHAR(10)

SELECT @sql2 = @sql2 +
'   , MAX(CASE WHEN RN = ' + CONVERT(VARCHAR(3), RN) + ' THEN componentID END) AS ' + QUOTENAME(RN) + CHAR(10)
FROM(   
    SELECT DISTINCT RN = ROW_NUMBER() OVER(PARTITION BY recipeID ORDER BY componentID)
    FROM tbl    
)b

SELECT @sql2 = @sql2 +
'   , MAX(CASE WHEN RN = ' + CONVERT(VARCHAR(3), RN + 10) + ' THEN [count] END) AS ' + QUOTENAME(RN) + CHAR(10)
FROM(   
    SELECT DISTINCT RN = ROW_NUMBER() OVER(PARTITION BY recipeID ORDER BY componentID)
    FROM tbl    
)b

SELECT @sql3 = 
'FROM(
    SELECT *,
        RN = ROW_NUMBER() OVER(PARTITION BY recipeID ORDER BY componentID)
    FROM tbl
)t
GROUP BY recipeID'

PRINT (@sql1 + @sql2 + @sql3)
EXEC (@sql1 + @sql2 + @sql3)

<强>结果

recipeID    1           2           3           4           11          12          13          14
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
9           21          NULL        NULL        NULL        5           NULL        NULL        NULL
12          3           30          34          96          1           1           1           1
27          29          43          NULL        NULL        1           1           NULL        NULL
28          29          44          NULL        NULL        1           1           NULL        NULL