简体   繁体   English

具有未知列数的简单SQL Pivot查询

[英]Simple SQL Pivot query with unknown number of columns

I have this sample data: 我有这个样本数据:

Item  Location
A   K
A   X
B   W
B   Z
B   Y
C   L

I'd like to have a result like this: 我想得到这样的结果:

Item    Loc1    Loc2    Loc3
A       K       X
B       W       Z       Y
C       L

Is it possibile using SQL Pivot operator? 是否可以使用SQL Pivot运算符?

I prefer conditional aggregation: 我更喜欢条件聚合:

select item,
       max(case when seqnum = 1 then location end) as location_1,
       max(case when seqnum = 2 then location end) as location_2,
       max(case when seqnum = 3 then location end) as location_3
from (select t.*, 
             row_number() over (partition by loc order by loc) as seqnum
      from t
     ) t
group by item;

Here is one method of using pivot query syntax with dynamic sql to generate the columns in the format you require. 下面是一种使用带有动态sql的数据透视查询语法来生成所需格式的列的方法。

Firstly I use a table variable to store the column names, this is generated using a window function that partitions on the item and then orders on the location and combining that with 'Loc' to generate Loc1, Loc2 etc. 首先,我使用表变量来存储列名,这是使用窗口函数生成的,该函数对项进行分区,然后在该位置进行排序,并将其与“Loc”组合以生成Loc1,Loc2等。

Then I pipe these into a variable which will form the column list. 然后我将这些管道传输到一个变量中,该变量将形成列列表。 This is done with a while loop to add each new column sequentially. 这是通过while循环完成的,以按顺序添加每个新列。

From there I tidy up the column list to remove trailing commas. 从那里我整理列列表以删除尾随逗号。

After that I generate the sql statement parsing the column variable in at the relevant points. 之后,我生成了在相关点解析列变量的sql语句。 I then execute this which generates the required result set. 然后我执行它生成所需的结果集。

create table #table (
    item char(1),
    location char(1)
);

insert #table (item, location)
values
('A',   'K'),
('A',   'X'),
('B',   'W'),
('B',   'Z'),
('B',   'Y'),
('C',   'L');

declare @pivotcols nvarchar(max)='';
declare @sql nvarchar(max)='';

declare @cols table (
colname nvarchar(150),
rowno int
);


insert @cols
select distinct '[Loc'+cast(rowno as nvarchar(10))+'],', rowno from
(
select row_number()over(partition by item order by location) as rowno,
       item, location 
from #table t)colgenerator;

while exists (select 1 from @cols)
    begin
    select top 1 @pivotcols = @pivotcols+colname from @cols order by rowno;
    delete from @cols where rowno in (select top 1 rowno from @cols order by rowno);
    end


select @pivotcols=substring(@pivotcols, 1, len(@pivotcols)-1);

select @sql=N'select item, '+@pivotcols+'
from (
select rowno, item, location from
(
select ''Loc''+cast(row_number()over(partition by item order by location) as nvarchar(1000)) as rowno,
       item, location 
from #table t)x)src
pivot (max(location) for rowno in ('+@pivotcols+')) piv;';


exec(@sql);

drop table #table;

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM