2017-02-13 2 views
0

Мне нужно написать запрос SQL-сервера для поворота данных из исходной таблицы.sql server pivot query - требуется помощь

Мой источник таблица выглядит следующим образом - главная таблица

Cust_Id Item1_Desc_Count Item2_Desc_Count Item3_Desc_Count 
------- ---------------- ---------------- ------------ 
Cust1 10     12     9 
Cust2 7     1     3 
Cust3 12     6     0 
... 

Item выглядит так -

Item_Id Item_Desc 
------- --------- 
1  Item1_Desc 
2  Item2_Desc 
3  Item3_Desc 

Пожалуйста, обратите внимание, что описание товара используются в именах столбцов в исходной таблице.

И мне нужна моя выход быть -

Cust_Id Item_Id Count 
-------- --------- ------ 
Cust1  1   10 
Cust1  2   12 
Cust1  3   9 
Cust2  1   7 
Cust2  2   1 
Cust2  3   3 
Cust3  1   12 
... 

Может кто-нибудь помочь мне достичь этого с помощью запроса SQL?

ответ

2

Это более динамичный подход. Не нужно указывать все столбцы «Количество элементов».

CROSS ОТНОСИТЬСЯ будет UNPIVOT Источник таблицы.

Я должен добавить, что UNPIVOT будет более результативным, но я предполагаю, что у вас много столбцов подсчета.


Создание Примеры данных

Declare @Source table (Cust_Id varchar(25),Item1_Desc_Count int,Item2_Desc_Count int,Item3_Desc_Count int) 
Insert Into @Source values 
('Cust1',10,12,9), 
('Cust2', 7, 1,3), 
('Cust3',12, 6,0) 

Declare @Item table (Item_Id int,Item_Desc varchar(50)) 
Insert Into @Item values 
(1,'Item1_Desc'), 
(2,'Item2_Desc'), 
(3,'Item3_Desc') 

Пример кода

Select B.Cust_ID 
     ,C.Item_ID 
     ,Count = B.Value 
From (Select XMLData = cast((Select * From @Source for XML Raw) as XML)) A 
Cross Apply (
       Select Cust_ID = r.value('@Cust_Id','varchar(50)') 
         ,Item = attr.value('local-name(.)','varchar(100)') 
         ,Value = attr.value('.','varchar(max)') 
       From A.XMLData.nodes('/row') as A(r) 
       Cross Apply A.r.nodes('./@*') AS B(attr) 
       Where attr.value('local-name(.)','varchar(100)') not in ('Cust_ID','OtherFieldsToExclude') 
      ) B 
Join @Item C on B.Item Like C.Item_Desc+'%' 

Возвращает

Cust_ID Item_ID Count 
Cust1 1  10 
Cust1 2  12 
Cust1 3  9 
Cust2 1  7 
Cust2 2  1 
Cust2 3  3 
Cust3 1  12 
Cust3 2  6 
Cust3 3  0 

EDIT - UNPIVOT Опция

Select A.Cust_ID 
     ,B.Item_ID 
     ,Count = A.Value 
From (
     Select Cust_Id,Item,value 
     From @Source 
     Unpivot (Value for Item in (Item1_Desc_Count,Item2_Desc_Count,Item3_Desc_Count)) u 
     ) A 
Join @Item B on A.Item Like B.Item_Desc+'%' 
0

Если я понимаю, вы хотели бы присоединиться к вам имена столбцов таблицы источника с содержанием вашей основной таблицы.

Сверль не работает таким образом. Поворотный, когда вы хотите превратить ваши данные как

Cust1 10 7 12 Cust2 12 1 6 Cust3 9 3 0

(проверить это Exemple: https://blogs.msdn.microsoft.com/spike/2009/03/03/pivot-tables-in-sql-server-a-simple-sample/)

В этом случае, я вижу это решение (но ITEM_ID будет жестко):

select Cust_Id, 1, Item1_Desc_Count as count FROM SourceTable UNION ALL select Cust_Id, 2, Item2_Desc_Count as count FROM SourceTable UNON ALL ...etc

Я согласен, что это не очень элегантно, но это простой и гибкий, если не идеальный матч между именами столбцов исходной таблицы и item_descs в т он мастер стол