Простой свод данных

#sql #sql-server #pivot

#sql #sql-сервер #свод

Вопрос:

У меня есть запрос (выберите [тип], a, b, c, d, e из MyTable), который возвращает:

 [type], [a], [b], [c], [d], [e]
type 1,  x ,  x ,  x ,  x ,  x
type 2,  x ,  x ,  x ,  x ,  x
type 3,  x ,  x ,  x ,  x ,  x
  

Я хотел бы повернуть данные так, чтобы они отображались как:

 []     , [type 1], [type 2], [type 3] 
[a]    , x       , x       , x
[b]    , x       , x       , x
[c]    , x       , x       , x
[d]    , x       , x       , x 
[e]    , x       , x       , x   
  

Любые указания на SQL здесь были бы оценены.

Комментарии:

1. Столбцы a, b, c, d, e фиксированы, но может быть X количество строк (типов)

2. Мне просто нужно повернуть таблицу, данные не нуждаются в группировке, т. Е. Типы в столбце [тип] всегда будут уникальными.

Ответ №1:

Что нам нужно, так это:

 SELECT  Col, [type 1], [type 2], [type 3]
FROM    (SELECT [type], Amount, Col
         FROM   (SELECT [type], [a], [b], [c], [d], [e]
                FROM    _MyTable) as sq_source
                UNPIVOT (Amount FOR Col IN ([a], [b], [c], [d], [e])) as sq_up) as sq 
PIVOT (MIN(Amount) FOR [type] IN ([type 1], [type 2], [type 3])) as p;
  

Но поскольку число типов не определено, мы должны делать это динамически

 DECLARE @cols NVARCHAR(2000)
SELECT  @cols = COALESCE(@cols   ',['   [type]   ']',
                         '['   [type]   ']')
FROM    _MyTable
ORDER BY [type]

DECLARE @query NVARCHAR(4000)
SET @query = N'SELECT   Col, '   @cols   '
FROM    (SELECT [type], Amount, Col
         FROM   (SELECT [type], [a], [b], [c], [d], [e]
                FROM    _MyTable) as sq_source
                UNPIVOT (Amount FOR Col IN ([a], [b], [c], [d], [e])) as sq_up) as sq 
PIVOT (MIN(Amount) FOR [type] IN ('   @cols   ')) as p;';

EXECUTE(@query)
  

Но будьте осторожны, потому что технически этот запрос является вектором для внедрения.

Комментарии:

1. Стоит отметить, что, даже если вы изменили @cols и @query на nvarchar(max), это приведет к разрыву для чего-либо большего, чем 4096 types . Смотрите здесь: msdn.microsoft.com/en-us/library/ms143432.aspx

2. Спасибо, это именно то, что я хочу на данный момент. Я буду работать над проблемой внедрения позже!

Ответ №2:

Что-то вроде этого?

 create table #test
(
type varchar(10),
a varchar(10),
b varchar(10),
c varchar(10),
d varchar(10),
e varchar(10)
)

insert into #test values
('type 1',  'x' ,  'x' ,  'x' ,  'x'  , 'x'),
('type 2',  'x' ,  'x' ,  'x' ,  'x' ,  'x'),
('type 3',  'x' ,  'x' ,  'x' ,  'x' ,  'x')

select * from
(

   select * from
   (
      select * from #test
   )data_to_unpivot
   UNPIVOT
   (
   Orders FOR [xxx] IN (a,b,c,d,e)

   )UNPIVOTED_DATA 
)data_to_pivot
PIVOT
(
MAX(orders) for type in ([type 1],[type 2],[type 3])
)PIVOTED_DATA   
  

Комментарии:

1. Это жестко кодирует типы (тип 1, тип 2, тип 3). Ранее я отмечал, что типы являются переменными.