Как найти первую ненулевую запись для каждого столбца и группы по идентификатору - PullRequest
0 голосов
/ 18 июня 2019

У меня есть таблица, в которой хранятся события, и я хочу создать представление о последнем / текущем состоянии для каждого идентификатора.
Каждая строка в таблице должна быть построена из ненулевых записей с наивысшим соответствующим порядковым номером.
Порядковый номер переносится событием. Мои навыки работы с SQL немного устарели, поскольку я в основном работал с Cassandra.

Я провел целый день, выясняя, как это сделать, и перепробовал кучу вещей, например. используя COALESCE, FIRST_VALUE и различные запросы sub 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 голосов
/ 18 июня 2019

Если вы продолжите настаивать, результаты придут :-) Мне удалось это выяснить.Для всех, кто заинтересован, вот код:

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]

Я не знаю, как будет выполняться запрос, но в моем сценарии он подойдет.Пожалуйста, дайте мне знать, если вы обнаружите какие-либо недостатки.Улучшения всегда приветствуются.

0 голосов
/ 18 июня 2019

Одним простым решением было бы использование старых добрых подзапросов.

Сначала создайте и заполните образец таблицы ( Пожалуйста, сохраните этот шаг в своих будущих вопросах):

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...