TSQL PIVOT从2列从1到标题

时间:2018-12-07 15:04:31

标签: sql-server database tsql pivot

我正在尝试旋转这张桌子

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 :(得分:0)

我认为您无法使用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

它将返回与您在表中具有的不同代码一样多的列,并且在每一列中它将在第一行中返回此代码的相关值。为此,我将计算每个代码的行号并加入其中。可以使用over子句中的partition by col1在单个CTE中计算此行号,并多次连接同一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;