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