2013-02-26 2 views
1

Я пытаюсь получить чистую сводную таблицу для нескольких столбцов.Динамическая сводная таблица с несколькими колонками

Создание таблицы ввода

create table #temp (
    ORDER_ID INT NOT NULL, 
    TEST_PLAN INT NOT NULL, 
    COLLECTION_TYPE INT NOT NULL, 
    TEST_GRP INT NOT NULL, 
    TEST INT NOT NULL 
) 

INSERT INTO #temp (ORDER_ID,TEST_PLAN,COLLECTION_TYPE,TEST_GRP,TEST) VALUES (1,1,2,1360942998,1360943100) 
INSERT INTO #temp (ORDER_ID,TEST_PLAN,COLLECTION_TYPE,TEST_GRP,TEST) VALUES (2,1,2,1360943006,1360943079) 
INSERT INTO #temp (ORDER_ID,TEST_PLAN,COLLECTION_TYPE,TEST_GRP,TEST) VALUES (1,2,2,1360942845,1360943173) 
INSERT INTO #temp (ORDER_ID,TEST_PLAN,COLLECTION_TYPE,TEST_GRP,TEST) VALUES (2,2,2,1360942845,1360943134) 
INSERT INTO #temp (ORDER_ID,TEST_PLAN,COLLECTION_TYPE,TEST_GRP,TEST) VALUES (3,2,2,1360942845,1360943189) 
INSERT INTO #temp (ORDER_ID,TEST_PLAN,COLLECTION_TYPE,TEST_GRP,TEST) VALUES (1,3,2,1360942998,1360943100) 

Результат ...

ORDER_ID PLAN COLLECTION_TYPE TEST_GRP TEST   
-------- ---- --------------- ---------- ---------- 
1  1 2    1360942998 1360943100 
2  1 2    1360943006 1360943079 
1  2 1    1360942845 1360943173 
2  2 1    1360942845 1360943134 
3  2 1    1360942845 1360943189 
1  3 2    1360942998 1360943100 

Я хотел следующее, где ORDER_ID прилагается к COLLECTION_TYPE, TEST_GRP и ИСПЫТАНИЙ колонны

PLAN COLLECTION_TYPE_1 TEST_GRP_1 TEST_1  COLLECTION_TYPE_2 TEST_GRP_2 TEST_2  COLLECTION_TYPE_3 TEST_GRP_3 TEST_3 
---- ----------------- ---------- ---------- ----------------- ---------- ---------- ----------------- ---------- ---------- 
1 2     1360942998 1360943100 2     1360943006 1360943079 NULL    NULL  NULL 
2 1     1360942845 1360943173 1     1360942845 1360943134 1     1360942845 1360943189 
3 2     1360942998 1360943100 NULL    NULL  NULL  NULL    NULL  NULL 

У меня есть это, и он работает, но искал что-то немного чище (например, несколько нулей) ,

DECLARE @SQL NVARCHAR(MAX), 
     @Cols NVARCHAR(MAX) 

SELECT @cols = STUFF((select ', 
MAX(CASE WHEN [TEST_PLAN]=' + CONVERT(VARCHAR,[TEST_PLAN]) + ' AND [ORDER_ID] = ' + CONVERT(VARCHAR,[ORDER_ID]) + 
' THEN [TEST_GRP] ELSE NULL END) AS [TEST_GRP_' + CONVERT(VARCHAR,[ORDER_ID]) + '], 
MAX(CASE WHEN [TEST_PLAN]=' + CONVERT(VARCHAR,[TEST_PLAN]) + ' AND [ORDER_ID] = ' + CONVERT(VARCHAR,[ORDER_ID]) + 
' THEN [TEST_GRP] ELSE NULL END) AS [TEST_' + CONVERT(VARCHAR,[ORDER_ID]) + '], 
MAX(CASE WHEN [TEST_PLAN]=' + CONVERT(VARCHAR,[TEST_PLAN]) + ' AND [ORDER_ID] = ' + CONVERT(VARCHAR,[ORDER_ID]) + 
' THEN [COLLECTION_TYPE] ELSE NULL END) AS [COLLECTION_TYPE_' + CONVERT(VARCHAR,[ORDER_ID]) + ']' 
FROM #temp 
ORDER BY [TEST_PLAN],[ORDER_ID] FOR XML PATH(''),type).value('.','varchar(max)'),1,2,'') 

SET @SQL = 'SELECT TEST_PLAN,' + @Cols + ' FROM #Temp GROUP BY TEST_PLAN' 

EXECUTE(@SQL) 

Существует выход ...

TEST_PLAN TEST_GRP_1 TEST_1  COLLECTION_TYPE_1 TEST_GRP_2 TEST_2  COLLECTION_TYPE_2 TEST_GRP_1 TEST_1  COLLECTION_TYPE_1 TEST_GRP_2 TEST_2  COLLECTION_TYPE_2 TEST_GRP_3 TEST_3  COLLECTION_TYPE_3 TEST_GRP_4 TEST_4  COLLECTION_TYPE_4 TEST_GRP_5 TEST_5  COLLECTION_TYPE_5 TEST_GRP_6 TEST_6  COLLECTION_TYPE_6 TEST_GRP_7 TEST_7  COLLECTION_TYPE_7 TEST_GRP_8 TEST_8  COLLECTION_TYPE_8 TEST_GRP_9 TEST_9  COLLECTION_TYPE_9 TEST_GRP_10 TEST_10  COLLECTION_TYPE_10 TEST_GRP_1 TEST_1  COLLECTION_TYPE_1 
----------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ----------------- ----------- ----------- ------------------ ----------- ----------- ----------------- 
1   1360942998 1360942998 2     1360943006 1360943006 2     NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL 
2   NULL  NULL  NULL    NULL  NULL  NULL    1360942845 1360942845 2     1360942845 1360942845 2     1360942845 1360942845 2     1360942845 1360942845 2     1360942845 1360942845 2     1360942845 1360942845 2     1360942845 1360942845 2     1360942845 1360942845 2     1360942845 1360942845 2     1360942845 1360942845 2     NULL  NULL  NULL 
3   NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    NULL  NULL  NULL    1360942998 1360942998 2 

Я искал решение с ближайшим быть выше SQL.

Благодаря jlimited

ответ

1

Для того, чтобы получить результат, который вы хотите, я должен был бы использовать как UNPIVOT и PIVOT функции. UNPIVOT примет ваши значения из столбцов и преобразует их в строки, а PIVOT берет строки и преобразует их обратно в столбцы.

Иногда проще сначала использовать статическую или жестко запрограммированную версию запроса, а затем преобразовать в динамический SQL. Статическая версия будет:

select [Plan], 
    Isnull(COLLECTION_TYPE_1, '') COLLECTION_TYPE_1, 
    Isnull(TEST_GRP_1, '') TEST_GRP_1, 
    Isnull(TEST_1, '') TEST_1, 
    Isnull(COLLECTION_TYPE_2, '') COLLECTION_TYPE_2, 
    Isnull(TEST_GRP_2, '') TEST_GRP_2, 
    Isnull(TEST_2, '') TEST_2, 
    Isnull(COLLECTION_TYPE_3, '') COLLECTION_TYPE_3, 
    Isnull(TEST_GRP_3, '') TEST_GRP_3, 
    Isnull(TEST_3, '') TEST_3 
from 
(
    select [PLAN], col + '_'+ cast(ORDER_ID as varchar(50)) col, value 
    from 
    (
    select ORDER_ID,[PLAN],COLLECTION_TYPE,TEST_GRP,TEST 
    from temp 
) s 
    unpivot 
    (
    value 
    for col in (COLLECTION_TYPE,TEST_GRP,TEST) 
) unpiv 
) src 
pivot 
(
    max(value) 
    for col in (COLLECTION_TYPE_1, TEST_GRP_1, TEST_1, 
       COLLECTION_TYPE_2, TEST_GRP_2, TEST_2, 
       COLLECTION_TYPE_3, TEST_GRP_3, TEST_3) 
) piv 

См SQL Fiddle with Demo.

Как только у вас есть статическая версия, вы можете легко преобразовать ее в динамический SQL. При создании динамического SQL вы можете создать список столбцов, который заменяет значения null пустой строкой или другим значением, которое очищает nulls. Динамический код SQL является:

DECLARE @cols AS NVARCHAR(MAX), 
    @colsNames AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT ',' + QUOTENAME(col + '_'+ cast(ORDER_ID as varchar(50))) 
        from temp t 
        cross apply 
        (
         select 'COLLECTION_TYPE' col, 1 SortOrder 
         union all 
         select 'TEST_GRP' col, 2 SortOrder 
         union all 
         select 'TEST' col, 3 SortOrder 
        ) c 
        group by col, ORDER_ID, sortorder 
        order by ORDER_ID, sortorder 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

select @colsNames = STUFF((SELECT ', IsNull(' + QUOTENAME(col + '_'+ cast(ORDER_ID as varchar(50)))+', '''') as '+QUOTENAME(col + '_'+ cast(ORDER_ID as varchar(50))) 
        from temp t 
        cross apply 
        (
         select 'COLLECTION_TYPE' col, 1 SortOrder 
         union all 
         select 'TEST_GRP' col, 2 SortOrder 
         union all 
         select 'TEST' col, 3 SortOrder 
        ) c 
        group by col, ORDER_ID, sortorder 
        order by ORDER_ID, sortorder 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT [PLAN],' + @colsNames + ' from 
      (
       select [PLAN], col + ''_''+ cast(ORDER_ID as varchar(50)) col, value 
       from 
       (
        select ORDER_ID,[PLAN],COLLECTION_TYPE,TEST_GRP,TEST 
        from temp 
       ) s 
       unpivot 
       (
        value 
        for col in (COLLECTION_TYPE,TEST_GRP,TEST) 
       ) unpiv 
      ) src 
      pivot 
      (
       max(value) 
       for col in (' + @cols + ') 
      ) p ' 

execute(@query) 

См SQL Fiddle with Demo

Оба дают результат:

| PLAN | COLLECTION_TYPE_1 | TEST_GRP_1 |  TEST_1 | COLLECTION_TYPE_2 | TEST_GRP_2 |  TEST_2 | COLLECTION_TYPE_3 | TEST_GRP_3 |  TEST_3 | 
-------------------------------------------------------------------------------------------------------------------------------------------------- 
| 1 |     2 | 1360942998 | 1360943100 |     2 | 1360943006 | 1360943079 |     0 |   0 |   0 | 
| 2 |     1 | 1360942845 | 1360943173 |     1 | 1360942845 | 1360943134 |     1 | 1360942845 | 1360943189 | 
| 3 |     2 | 1360942998 | 1360943100 |     0 |   0 |   0 |     0 |   0 |   0 | 
Смежные вопросы