Sql server sql server pivot 2值

Sql server sql server pivot 2值,sql-server,pivot,sql-server-2014-express,Sql Server,Pivot,Sql Server 2014 Express,我试图在一行中得到两个值 示例数据: 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

我试图在一行中得到两个值

示例数据:

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
我试过两个支点,但我都失败了

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 像往常一样,对外部查询中的列使用聚合函数(sum或max),并使用
group by

SELECT 
    recipeID
    , SUM([1]) [1]
    , SUM([2]) [2]
    , SUM([3]) [3]
    , SUM([4]) [4]
    , SUM([11]) [11]
    , SUM([12]) [12]
    , SUM([13]) [13]
    , SUM([14]) [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;
结果:

| 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 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
给你一个


希望这有帮助

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

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函数关闭了正在透视的表中的所有字段。我在我的中用一个例子解释了这一点。

这里是另一个使用动态交叉表的解决方案:

结果

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

当计数仅为5,1时,1,2,3,4,11,12等是计数和项目的唯一列名。4是配方中项目的最大数量
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
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