Получить пропущенные записи с отсутствующей датой и обновить значение с предыдущим ненулевым значением - PullRequest
1 голос
/ 02 апреля 2020

У меня есть следующая таблица, где учителя ежедневно обновляют данные, но некоторые учителя не обновляют записи ежедневно. Мне нужно найти пропущенную дату и добавить предыдущее значение NOT NULL в поля Val и TotalValue. У меня есть таблица дат, и я оставил соединение с таблицей дат, но не смог обновить ненулевые записи. 2 января и 3 января отсутствуют строки, мне нужно добавить строки к результату

DECLARE @Table TABLE(
        ID INT,
        ClassID VARCHAR(10),
        Val INT,
        TotalValue INT,
        UpdatedDateTime DATETIME2

)

INSERT INTO @Table (ID, ClassID, Val,TotalValue, UpdatedDateTime) SELECT 1, 'AB475', 20, 100, '2020/1/1 14:00:20'
INSERT INTO @Table (ID, ClassID, Val,TotalValue, UpdatedDateTime) SELECT 1, 'ZXCV5', 50, 70, '2020/1/1 14:00:20'
INSERT INTO @Table (ID, ClassID, Val,TotalValue, UpdatedDateTime) SELECT 1, 'GHT09', 40, 40, '2020/1/1 14:00:20'
INSERT INTO @Table (ID, ClassID, Val,TotalValue, UpdatedDateTime) SELECT 1, 'AB475', 70, 100, '2020/1/2 14:00:20'
INSERT INTO @Table (ID, ClassID, Val,TotalValue, UpdatedDateTime) SELECT 1, 'GHT09', 38, 40, '2020/1/2 14:00:20'
INSERT INTO @Table (ID, ClassID, Val,TotalValue, UpdatedDateTime) SELECT 1, 'AB475', 20, 100, '2020/1/3 14:00:20'
INSERT INTO @Table (ID, ClassID, Val,TotalValue, UpdatedDateTime) SELECT 1, 'ZXCV5', 20, 70, '2020/1/3 14:00:20'

SELECT * FROM @Table

ID  ClassID Val TotalValue  UpdatedDateTime
1   AB475   20  100 2020-01-01 14:00:20.0000000
1   ZXCV5   50  70  2020-01-01 14:00:20.0000000
1   GHT09   40  40  2020-01-01 14:00:20.0000000
1   AB475   70  100 2020-01-02 14:00:20.0000000
1   GHT09   38  40  2020-01-02 14:00:20.0000000
1   AB475   20  100 2020-01-03 14:00:20.0000000
1   ZXCV5   20  70  2020-01-03 14:00:20.0000000

SELECT *
FROM [DATE]
LEFT JOIN @Table
    ON [DATE].[DATE] = CAST([@Table].UpdatedDateTime AS DATE)

Конечный результат должен быть

ID  ClassID Val TotalValue  UpdatedDateTime
1   AB475   20  100 2020-01-01 14:00:20.0000000
1   ZXCV5   50  70  2020-01-01 14:00:20.0000000
1   GHT09   40  40  2020-01-01 14:00:20.0000000
1   AB475   70  100 2020-01-02 14:00:20.0000000
1   GHT09   38  40  2020-01-02 14:00:20.0000000
1   AB475   20  100 2020-01-03 14:00:20.0000000
1   ZXCV5   20  70  2020-01-03 14:00:20.0000000
1   ZXCV5   50  70  2020-01-02 14:00:20.0000000
1   GHT09   38  40  2020-01-03 14:00:20.0000000

1 Ответ

1 голос
/ 02 апреля 2020

Я бы cross join два select distinct запроса, чтобы сгенерировать все возможные комбинации учителей и дат, а затем использовать cross apply, чтобы получить недостающую информацию:

select c.ID, c.ClassID, t.Val, t.TotalValue, d.UpdatedDateTime
from (select distinct ID, ClassID from @table) c
cross join (select distinct UpdatedDateTime from @table) d
cross apply (
    select top 1 *
    from @table t
    where t.ClassID = c.ClassID and t.UpdatedDateTime <= d.UpdatedDateTime
    order by t.UpdatedDateTime desc
) t
order by c.ID, c.classId, d.UpdatedDateTime

Демо на БД Fiddle :

ID | ClassID | Val | TotalValue | UpdatedDateTime            
-: | :------ | --: | ---------: | :--------------------------
 1 | AB475   |  20 |        100 | 2020-01-01 14:00:20.0000000
 1 | AB475   |  70 |        100 | 2020-01-02 14:00:20.0000000
 1 | AB475   |  20 |        100 | 2020-01-03 14:00:20.0000000
 1 | GHT09   |  40 |         40 | 2020-01-01 14:00:20.0000000
 1 | GHT09   |  38 |         40 | 2020-01-02 14:00:20.0000000
 1 | GHT09   |  38 |         40 | 2020-01-03 14:00:20.0000000
 1 | ZXCV5   |  50 |         70 | 2020-01-01 14:00:20.0000000
 1 | ZXCV5   |  50 |         70 | 2020-01-02 14:00:20.0000000
 1 | ZXCV5   |  20 |         70 | 2020-01-03 14:00:20.0000000
...