在MSSQL 2008中合并行,

Bo *_*son 4 sql t-sql sql-server coalesce sql-server-2008

我正在尝试确定MSSQL 2008中的最佳方法.

这是我的示例数据

TransDate  Id     Active
-------------------------
1/18 1pm   5      1    
1/18 2pm   5      0    
1/18 3pm   5      Null    
1/18 4pm   5      1    
1/18 5pm   5      0    
1/18 6pm   5      Null
Run Code Online (Sandbox Code Playgroud)

如果按Id分组并由TransDate排序,我想要活动列的最后一个非空值和TransDate的MAX

SELECT MAX(TransDate) AS TransDate, 
       Id,
       --LASTNonNull(Active) AS Active
Run Code Online (Sandbox Code Playgroud)

结果如下:

TransDate  Id  Active
---------------------    
1/18 6pm   5   0
Run Code Online (Sandbox Code Playgroud)

它就像一个Coalesce但是在行上,而不是两个值/列.

还有许多其他列也会应用这种类似的方法,所以我真的不想为每个列进行单独的连接.

有任何想法吗?

Mar*_*ith 5

我可能会使用相关的子查询.

SELECT MAX(TransDate)             AS TransDate,
       Id,
       (SELECT TOP (1) Active
        FROM   T t2
        WHERE  t2.Id = t1.Id
               AND Active IS NOT NULL
        ORDER  BY TransDate DESC) AS Active
FROM   T t1
GROUP  BY Id  
Run Code Online (Sandbox Code Playgroud)

一种没有的方式

SELECT
    Id,
    MAX(TransDate) AS TransDate,
    CAST(RIGHT(MAX(CONVERT(CHAR(23),TransDate,121) + CAST(Active AS CHAR(1))),1) AS BIT) AS Active,
    /*You can probably figure out a more efficient thing to 
    compare than the above depending on your data. e.g.*/
    CAST(MAX(DATEDIFF(SECOND,'19500101',TransDate) * CAST(10 AS BIGINT) + Active)%10  AS BIT) AS Active2
FROM T
GROUP BY Id
Run Code Online (Sandbox Code Playgroud)

或者跟随评论会cross apply更好地为您服务?

WITH T (TransDate, Id, Active, SomeOtherColumn) AS
(
select GETDATE(), 5, 1, 'A' UNION ALL
select 1+GETDATE(), 5, 0, 'B' UNION ALL
select 2+GETDATE(), 5, null, 'C' UNION ALL
select 3+GETDATE(), 5, 1, 'D' UNION ALL
select 4+GETDATE(), 5, 0, 'E' UNION ALL
select 5+GETDATE(), 5, null,'F'

),
T1 AS
(
SELECT MAX(TransDate) AS TransDate,
       Id
FROM   T
GROUP  BY Id  
)
SELECT T1.TransDate,
       Id,
       CA.Active AS Active,
       CA.SomeOtherColumn AS SomeOtherColumn
FROM   T1
CROSS APPLY (SELECT TOP (1) Active, SomeOtherColumn
        FROM   T t2
        WHERE  t2.Id = T1.Id
               AND Active IS NOT NULL
        ORDER  BY TransDate DESC) CA
Run Code Online (Sandbox Code Playgroud)