将多行合并为一行,但基于值具有新行

时间:2012-10-04 21:40:54

标签: sql common-table-expression sql-server-2012

我想将多行合并为一行,但当字段中出现某个值时会有一个新行,请参阅下面的示例数据

目前数据的表格如何

IncomingNumber  QueNumber Datetime
--------------  --------- -------------------
12345678        1         2012-01-01 09:01:00
12345678        2         2012-01-01 09:02:00
12345678        3         2012-01-01 09:05:00
12345678        2         2012-01-01 09:07:00
12345678        3         2012-01-01 09:08:00
12345678        1         2012-01-01 09:10:00
12345678        2         2012-01-01 09:11:00
12345678        3         2012-01-01 09:13:00
09876543        1         2012-01-01 09:01:00
09876543        2         2012-01-01 09:02:00
09876543        1         2012-01-01 09:05:00
09876543        2         2012-01-01 09:06:00
09876543        3         2012-01-01 09:08:00

我希望数据看起来像

IncomingNumber  Datetime1            Datetime2            Datetime3            Datetime4            Datetime5
--------------  -------------------  -------------------  -------------------  -------------------  -------------------
12345678        2012-01-01 09:01:00  2012-01-01 09:02:00  2012-01-01 09:05:00  2012-01-01 09:07:00  2012-01-01 09:08:00
12345678        2012-01-01 09:10:00  2012-01-01 09:11:00  2012-01-01 09:13:00  Null                 Null
09876543        2012-01-01 09:01:00  2012-01-01 09:02:00  Null                 Null                 Null
09876543        2012-01-01 09:05:00  2012-01-01 09:06:00  2012-01-01 09:08:00  Null                 Null 

因此,每次在QueNumber字段中出现1时,它都是新记录。我知道它与CTE查询有关但我从来没有真正使用它们而且完全被卡住了

1 个答案:

答案 0 :(得分:3)

欢迎使用StackOverflow。如果您发布DDL和样本数据以帮助他们,它通常可以帮助其他人。这是你的桌子数据。

create table tbl (IncomingNumber int,QueNumber int,Datetime datetime);
insert tbl values
    (12345678 ,1 ,'2012-01-01 09:01:00'),
    (12345678 ,2 ,'2012-01-01 09:02:00'),
    (12345678 ,3 ,'2012-01-01 09:05:00'),
    (12345678 ,2 ,'2012-01-01 09:07:00'),
    (12345678 ,3 ,'2012-01-01 09:08:00'),
    (12345678 ,1 ,'2012-01-01 09:10:00'),
    (12345678 ,2 ,'2012-01-01 09:11:00'),
    (12345678 ,3 ,'2012-01-01 09:13:00'),
    (09876543 ,1 ,'2012-01-01 09:01:00'),
    (09876543 ,2 ,'2012-01-01 09:02:00'),
    (09876543 ,1 ,'2012-01-01 09:05:00'),
    (09876543 ,2 ,'2012-01-01 09:06:00'),
    (09876543 ,3 ,'2012-01-01 09:08:00');

以下查询为您提供所需内容,最多5个日期时间列。如果任何行产生超过5列,则不会显示附加内容。我使用的模式很容易让你扩展。从下往上计数,您只需要更改第2行和第4行以满足更多日期时间列。

;with c1 as (
    select *,rn=ROW_NUMBER() over (partition by IncomingNumber order by DateTime)
    from tbl
), c2 as (
    select IncomingNumber,1 row,1 col,rn,DateTime
    from c1
    where rn=1
    union all
    select c1.IncomingNumber,
            case when c1.QueNumber=1 then c2.row+1 else c2.row end,
            case when c1.QueNumber=1 then 1 else c2.col+1 end,
            c1.rn,
            c1.DateTime
    from c2
    join c1 on c1.IncomingNumber=c2.IncomingNumber and c1.rn=c2.rn+1
)
select IncomingNumber,[1][DateTime1],[2][DateTime2],[3][DateTime3],[4][DateTime4],[5][DateTime5]
from(select IncomingNumber,row,col,DateTime from c2)p
pivot(max(DateTime)for col in([1],[2],[3],[4],[5]))v
order by IncomingNumber,row