在数据透视列中排序而不在结果中
Posted
技术标签:
【中文标题】在数据透视列中排序而不在结果中【英文标题】:Order by in Pivot Column not in Result 【发布时间】:2021-03-14 12:05:07 【问题描述】:表-A
Productid | Brandname |
---|---|
1 | C Brand |
2 | K Brand |
3 | A Brand |
表-B
Productid | Rate | Slab |
---|---|---|
1 | 10 | 1 |
2 | 20 | 1 |
3 | 30 | 1 |
1 | 12 | 2 |
2 | 22 | 2 |
3 | 32 | 2 |
动态枢轴查询:-
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Brandname) from [Table-A] FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
set @query = 'SELECT Slab,' + @cols + '
from
(
select a.BrandName, b.Rate,b.Slab from [Table-A] a inner join [Table-B] b on a.productid=b.productid
) x
pivot
(
max(Rate)
for Brandname in (' + @cols + ')
) p '
execute(@query)
结果:-
Slab | A Brand | C Brand | K Brand |
---|---|---|---|
1 | 30 | 10 | 20 |
2 | 32 | 12 | 22 |
但我需要使用 productid 订购 Brandname 列
预期结果:-
Slab | C Brand | K Brand | A Brand |
---|---|---|---|
1 | 10 | 20 | 30 |
2 | 12 | 22 | 32 |
【问题讨论】:
【参考方案1】:在为动态数据透视准备列列表时,使用order by productid并删除 distinct,您的问题将得到解决。
架构和插入语句:
create table [Table-A](Productid int,Brandname varchar(10));
insert into [Table-A] values(1 ,'C Brand');
insert into [Table-A] values(2 ,'K Brand');
insert into [Table-A] values(3 ,'A Brand');
create table [Table-B] (Productid int, Rate int , Slab int)
insert into [Table-B] values(1 ,10 ,1);
insert into [Table-B] values(2 ,20 ,1);
insert into [Table-B] values(3 ,30 ,1);
insert into [Table-B] values(1 ,12 ,2);
insert into [Table-B] values(2 ,22 ,2);
insert into [Table-B] values(3 ,32,2);
查询:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(Brandname) from [Table-A] order by productid FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
set @query = 'SELECT Slab,' + @cols + '
from
(
select a.BrandName, b.Rate,b.Slab from [Table-A] a inner join [Table-B] b on a.productid=b.productid
) x
pivot
(
max(Rate)
for Brandname in (' + @cols + ')
) p '
execute(@query)
输出:
Slab | C Brand | K Brand | A Brand |
---|---|---|---|
1 | 10 | 20 | 30 |
2 | 12 | 22 | 32 |
如果您使用的是 SQL Server 2017 或更高版本,则 string_agg() 将是更智能、更快的选择。
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select distinct @cols=STRING_AGG(quotename(brandname),',') from [Table-A]
set @query = 'SELECT Slab,' + @cols + '
from
(
select a.BrandName, b.Rate,b.Slab from [Table-A] a inner join [Table-B] b on a.productid=b.productid
) x
pivot
(
max(Rate)
for Brandname in (' + @cols + ')
) p '
execute(@query)
输出:
Slab | C Brand | K Brand | A Brand |
---|---|---|---|
1 | 10 | 20 | 30 |
2 | 12 | 22 | 32 |
db小提琴here
【讨论】:
@Sathesh Kumar 如果您在此查询中遇到更多困难,请告诉我。 如果对您有帮助,请点击绿色检查以接受此答案。【参考方案2】:您希望列按特定顺序排列。根据您的数据,您似乎不需要子查询中的SELECT DISTINCT
。但如果你这样做,你可以使用聚合来代替:
select @cols = STUFF((SELECT ',' + QUOTENAME(Brandname)
FROM [Table-A]
GROUP BY BrandName
ORDER BY MIN(ProductId)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'
), 1, 1, '')
但是,没有聚合:
select @cols = STUFF((SELECT ',' + QUOTENAME(Brandname)
FROM [Table-A]
ORDER BY ProductId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'
), 1, 1, '');
一旦@cols
的顺序正确,查询的其余部分应该就位。
【讨论】:
以上是关于在数据透视列中排序而不在结果中的主要内容,如果未能解决你的问题,请参考以下文章