如何为每个列和ID按组查找第一个非空记录

时间:2019-06-18 13:35:13

标签: tsql sequence

我有一个存储事件的表,我想为每个ID创建最新/当前状态的视图。
表中的每一行应由具有最高对应序号的非空记录组成。
序列号由事件携带。 我的SQL技能有点生锈,因为我主要是在Cassandra工作。

我花了一整天的时间弄清楚该怎么做,并尝试了一堆东西,例如使用COALESCEFIRST_VALUE和其他子SELECT查询。因此,我认为失败的解决方案只会在此处发布,才会造成混乱。

这是包含事件的表:

|----|------|------|----------|
| Id | A    | B    | Sequence |
|----|------|------|----------|
| 1  | a0   | b0   | 0        |
|----|------|------|----------|
| 2  | a0   | b6   | 0        |
|----|------|------|----------|
| 1  | a1   | NULL | 1        |
|----|------|------|----------|
| 2  | a1   | NULL | 1        |
|----|------|------|----------|
| 2  | NULL | b2   | 2        |
|----|------|------|----------|
| 2  | a3   | b3   | 3        |
|----|------|------|----------|
| 2  | NULL | b4   | 4        |
|----|------|------|----------|

...以及要实现的视图:

|----|----|----|----------|
| Id | A  | B  | Sequence |
|----|----|----|----------|
| 1  | a1 | b0 | 1        |
|----|----|----|----------|
| 2  | a3 | b4 | 4        |
|----|----|----|----------|

2 个答案:

答案 0 :(得分:0)

一种简单的解决方案是使用良好的老式子查询。

首先,创建并填充示例表(在您将来的问题中为我们保存此步骤):

DECLARE @T AS TABLE
(
    Id int,
    A char(2),
    B char(2),
    Sequence int
)

INSERT INTO @T (Id, A, B, Sequence) VALUES
(1, 'a0', 'b0', 0),
(2, 'a0', 'b6', 0),
(1, 'a1', NULL, 1),
(2, 'a1', NULL, 1),
(2, NULL, 'b2', 2),
(2, 'a3', 'b3', 3),
(2, NULL, 'b4', 4);

查询:

SELECT  Id, 
        (
            -- get the last non-null A value for the specified Id
            SELECT TOP 1 A 
            FROM @T As T1
            WHERE T1.Id = T0.Id
            AND A IS NOT NULL
            ORDER BY Sequence DESC
        ) As A,
        (
            -- get the last non-null B value for the specified Id
            SELECT TOP 1 B 
            FROM @T As T1
            WHERE T1.Id = T0.Id
            AND B IS NOT NULL
            ORDER BY Sequence DESC
        ) As B,
        MAX(Sequence) As Sequence
FROM @T As T0
GROUP BY Id

结果:

Id  A   B   Sequence
1   a1  b0  1
2   a3  b4  4

答案 1 :(得分:0)

如果您继续努力,结果将会:-)我设法弄清楚了。对于任何有兴趣的人,下面是代码:

SELECT [id],
       [A] = (
           SELECT TOP (1) [A]
           FROM [dbo].[Table]
           WHERE [A] IS NOT NULL
               AND [Current].[Id] = [Id]
           ORDER BY [Sequence] DESC
       ),
       [B] = (
           SELECT TOP (1) [B]
           FROM [dbo].[Table]
           WHERE [B] IS NOT NULL
               AND [Current].[Id] = [Id]
           ORDER BY [Sequence] DESC
       ),
       [HighestSequence] = (
           SELECT TOP (1) [Sequence]
           FROM [dbo].[Table]
           WHERE [Current].[Id] = [Id]
           ORDER BY [Sequence] DESC
       )
FROM (SELECT [Id] FROM [dbo].[Table]) AS [Current]
GROUP BY [Id]

我不知道查询将如何执行,但在我的情况下将是合适的。 如果发现任何缺陷,请告诉我。不断欢迎改进。