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但是在行上,而不是两个值/列.
还有许多其他列也会应用这种类似的方法,所以我真的不想为每个列进行单独的连接.
有任何想法吗?
我可能会使用相关的子查询.
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)