TSQL PIVOT из 2 столбцов от 1 до заголовка - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь повернуть эту таблицу

COL1|   COL2
001|    |001-TIPOLOGIA
001|    |001-MATERIALE
002|    |002-TIPOLOGIA
002|    |002-MATERIALE
002|    |002-DIAMETRO_ESTERNO
002|    |002-LUNGHEZZA_FILETTATURA
004|    |004-TIPOLOGIA
004|    |004-DIAMETRO
006|    |006-TIPOLOGIA
006|    |006-MATERIALE
006|    |006-QUALITA
006|    |006-DIAMETRO_EXT
006|    |006-DIAMETRO_INT
006|    |006-SPESSORE
006|    |006-NORME_RIFERIMENTO
006|    |006-PEZZI_CONFEZIONE
007|    |007-TIPO_FILTRO
007|    |007-DIMENSIONE_FILTRO

, чтобы результат был следующим:

001             |002                    |004                |006                |007
001-TIPOLOGIA   |002-TIPOLOGIA          |004-TIPOLOGIA      |006-TIPOLOGIA      |007-TIPO_FILTRO
001-MATERIALE   |002-MATERIALE          |004-DIAMETRO       |006-MATERIALE      |007-DIMENSIONE_FILTRO
                |002-DIAMETRO_ESTERNO   |004-LUNGHEZZA      |006-QUALITA        |007-SPESSORE_CORPO
                |002-ALTEZZA_GOMMA      |004-MATERIALE      |006-DIAMETRO_EXT   |007-MATERIALE_CORPO
                |002-DIAMETRO_FILETTO   |PRENOTAZIONE       |006-DIAMETRO_INT   |
                |002-LUNGHEZZA_FILETTATURA|                 |006-SPESSORE       |
                                                            |006-NORME_RIFERIMENTO|
                                                            |006-PEZZI_CONFEZIONE|

Попытка запустить сводную таблицу, я не могу получить результат,Вопрос в том, как мне решить

1 Ответ

0 голосов
/ 07 декабря 2018

Я не думаю, что вы можете сделать это с помощью оператора PIVOT.И, безусловно, для этого вам понадобится динамический SQL.Я даже не уверен, что вы должны делать это с T-SQL.Может быть, приложение является лучшим местом для построения этой таблицы.В любом случае, вы были предупреждены!

Моя идея состоит в том, чтобы построить запрос следующим образом:

;with
cte001 as (select row_number() over(order by col1) as RowNo, col2 from #t where col1 = '001'),
cte002 as (select row_number() over(order by col1) as RowNo, col2 from #t where col1 = '002'),
cte004 as (select row_number() over(order by col1) as RowNo, col2 from #t where col1 = '004'),
cte006 as (select row_number() over(order by col1) as RowNo, col2 from #t where col1 = '006'),
cte007 as (select row_number() over(order by col1) as RowNo, col2 from #t where col1 = '007')
select  cte001.col2 as [001], cte002.col2 as [002], cte004.col2 as [004], cte006.col2 as [006], cte007.col2 as [007]
from (select row_number() over(order by col1) as RowNo from #t) AllRowNums
left join cte001 on cte001.RowNo = AllRowNums.RowNo
left join cte002 on cte002.RowNo = AllRowNums.RowNo
left join cte004 on cte004.RowNo = AllRowNums.RowNo
left join cte006 on cte006.RowNo = AllRowNums.RowNo
left join cte007 on cte007.RowNo = AllRowNums.RowNo
where coalesce( cte001.col2, cte002.col2, cte004.col2, cte006.col2, cte007.col2) is not null

Он вернет столько столбцов, сколько разных кодов у вас в таблице и в каждомстолбец будет возвращать в первых строках соответствующие значения для этого кода.Для этого я рассчитываю номер строки по коду и присоединяюсь к нему.Можно рассчитать этот номер строки в одном CTE, используя partition by col1 в предложении over, и присоединиться к одному и тому же cte несколько раз, но приведенный выше запрос кажется более понятным.

А вот весь код длясоздайте запрос, подобный приведенному выше:

drop table if exists #t;
create table #t(col1 varchar(10), col2 varchar(50));

insert into #t values
('001', '001-TIPOLOGIA'),
('001', '001-MATERIALE'),
('002', '002-TIPOLOGIA'),
('002', '002-MATERIALE'),
('002', '002-DIAMETRO_ESTERNO'),
('002', '002-LUNGHEZZA_FILETTATURA'),
('004', '004-TIPOLOGIA'),
('004', '004-DIAMETRO'),
('006', '006-TIPOLOGIA'),
('006', '006-MATERIALE'),
('006', '006-QUALITA'),
('006', '006-DIAMETRO_EXT'),
('006', '006-DIAMETRO_INT'),
('006', '006-SPESSORE'),
('006', '006-NORME_RIFERIMENTO'),
('006', '006-PEZZI_CONFEZIONE'),
('007', '007-TIPO_FILTRO'),
('007', '007-DIMENSIONE_FILTRO')

-- Construct the actual query
declare @sql nvarchar(max) = ';with';
select  @sql += CONCAT('
cte', col1, ' as (select row_number() over(order by col1) as RowNo, col2 from #t where col1 = ''', col1, '''),') from (select distinct col1 from #t) t
set @sql = SUBSTRING(@sql, 1, len(@sql) - 1); -- remove the last comma
set @sql += '
select';
select @sql += CONCAT(' cte', col1, '.col2 as [', col1, '],') from (select distinct col1 from #t) t
set @sql = SUBSTRING(@sql, 1, len(@sql) - 1); -- remove the last comma
set @sql += '
from (select row_number() over(order by col1) as RowNo from #t) AllRowNums';
select @sql += CONCAT('
left join cte', col1, ' on cte', col1, '.RowNo = AllRowNums.RowNo') from (select distinct col1 from #t) t
set @sql += '
where coalesce(';
select @sql += CONCAT(' cte', col1, '.col2,') from (select distinct col1 from #t) t
set @sql = SUBSTRING(@sql, 1, len(@sql) - 1); -- remove the last comma
set @sql += ') is not null'

--print @sql

exec sp_executesql @sql;
...