【问题标题】:TSQL PIVOT from 2 columns from 1 to headerTSQL PIVOT 从 2 列从 1 到标题
【发布时间】:2019-05-09 08:54:52
【问题描述】:

我正在尝试旋转此表

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|

试图运行一个支点我无法得到结果, 问题是我该如何解决

【问题讨论】:

  • 这总是那五列吗?还是需要动态的?
  • 是动态的,大约有 600 多列
  • 600 列?这对任何事情都有什么用?解决方案是使用动态枢轴。像这样。 stackoverflow.com/questions/10404348/…
  • 既然你说你“试图运行一个支点”,请发布你尝试了什么以及你遇到了什么错误。
  • 我对您的输出的担忧是“行”似乎没有任何意义。这是一些并排设置的列表。因此,您会发现 TSQL 不适合做您想做的事。在应用程序或报告层中管理这一点要好得多。

标签: sql-server database tsql pivot


【解决方案1】:

我认为您不能使用 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中使用over子句中的partition by col1计算这个行号,并多次加入同一个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;

【讨论】:

    猜你喜欢
    • 2022-01-09
    • 1970-01-01
    • 2013-11-04
    • 2012-06-20
    • 2018-11-08
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多