2015-07-28 3 views
0

Я пытаюсь получить 2 значения в одну строку.sql server pivot 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 
+0

что именно 1,2,3,4, 11,12 и т.д., когда у вас есть количество только 5,1 – mohan111

+0

. counts - уникальные имена столбцов для счета и элементов. 4 - максимальное количество предметов в рецепте – SeanC

ответ

0

Используйте статистическую функцию (сумма или макс) на столбцах во внешнем запросе вместе с 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; 

Sample SQL Fiddle и результат:

| 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) | 
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

Другим способу был бы сделать каждый стержень как подзапрос, а затем объединение их вместе:

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.

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