2015-08-16 2 views
1

Извините, это может быть немного вне сферы охвата сообщества здесь, но я хотел получить второе мнение.Выступление PIVOT и MERGE - есть ли лучший способ сделать это?

У меня есть таблица со следующей структурой

Table_1 
TYPE ITEM DATE  QTYA QTYB QTYC 
X  AAA  17/08/2015 100  200  300 
X  AAA  18/08/2015 100  170  240 
Y  BBB  17/08/2015 100  240  100 

мне нужно использовать эту таблицу в качестве источника для слияния, но целевая таблица отформатирована совершенно по-разному

Table_2 
ITEM QTYA_1 QTYA_2......QTYA_31 QTYB_1 QTYB_2 QTYB_3......QTYB_31 QTYC_1 QTYC_2....QTYC_31 

(число суффикс в основном в день месяца)

Я могу преобразовать таблицу 1 в формат таблицы 2, используя смесь UNION ALL и PIVOT, но производительность не так уж хороша - p поскольку я должен сохранить информацию в таблице temp сначала, прежде чем слить ее (каждый тип в таблице_1 имеет другую дату начала, и я не могу перезаписать предыдущие значения в таблице_2, начиная с другой даты - в основном мне нужно объединить таблицу 3 или 4 раза с различным типом элемента и другой датой запуска)

Вот что я до сих пор

SELECT TOP 0 * INTO #TEMP_PIVOT_TABLE 
INSERT INTO #TEMP_PIVOT_TABLE SELECT * FROM 
    (SELECT ITEM, 'QTYA_' + CONVERT(DATETIMEFROMPARTS(day,DATE) AS VARCHAR) as 'Quantity Type', QTY_A FROM TABLE_1 
     UNION_ALL 
    SELECT ITEM, 'QTYB_' + CONVERT(DATETIMEFROMPARTS(day,DATE) AS VARCHAR) as 'Quantity Type', QTY_B FROM TABLE_1 
     UNION_ALL 
    SELECT ITEM, 'QTYC_' + CONVERT(DATETIMEFROMPARTS(day,DATE) AS VARCHAR) as 'Quantity Type', QTY_C FROM TABLE_1 
    ) A 
    PIVOT 
    (SUM(QUANTITY) FOR QUANTITY_TYPE IN ([QTYA_1], [QTYA_2],.....[QTYA_31],[QTYB_1].....[QTYC_31],[QTYC_1].....[QTYC_31])) AS B 

----For each different date per item_type, construct a string only selecting those days in the month. 
Then merge the results from #TEMP_PIVOT_TABLE into TABLE_2 for each Item TYPE` with dynamic SQL 

1) есть ли лучший способ сделать команду PIVOT? Производительность команд UNION ALL не обнадеживает - особенно потому, что таблица, которую я читаю, содержит большие объемы данных. Я также упрощаю здесь для краткости - фактической таблице необходимо сопоставить 5 столбцов или около того, каждый из которых имеет 31 день

2) Есть ли лучший способ сделать MERGE? Мне не нравится использование цикла + Dynamic SQL, чтобы в основном читать один и тот же набор данных несколько раз, чтобы сливаться с разными столбцами, но я не вижу другого способа. Это и создание команды MERGE динамически с таким количеством столбцов сделают ее трудной для будущего обслуживания.

Есть ли у кого-нибудь идеи, как я могу это сделать более эффективно?

ответ

2

Вы можете заменить внутренний запрос union all следующим запросом. Для этого запроса требуется только один столбец, а не столбец для каждого столбца.

Чтобы UNPIVOT использование cross apply данных с table valued constructor

select ITEM,[Quantity Type],QTY 
from yourtable 
cross apply 
(
values 
('QTYA_' + CONVERT(DATEPART(day,DATE) AS VARCHAR),QTY_A), 
('QTYB_' + CONVERT(DATEPART(day,DATE) AS VARCHAR),QTY_B), 
('QTYC_' + CONVERT(DATEPART(day,DATE) AS VARCHAR),QTY_C), 
) 
CS ([Quantity Type],QTY) 
+0

Никогда не использовал [CROSS ОТНОСИТЬСЯ] перед тем, будет смотреть на него сейчас, спасибо! Любые предложения для головоломки MERGE? –

Смежные вопросы