Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

znajdź brakujące wpisy dla dni roboczych i wypełnij wiersz wartościami z najbliższej daty

W przypadku tego typu zapytań można uzyskać znaczne korzyści pod względem wydajności, tworząc tabelę kalendarza zawierającą wszystkie daty, które kiedykolwiek będziesz musiał przetestować. (Jeśli znasz termin „tabele wymiarów”, to jest to tylko jedna taka tabela, w której można wymienić wszystkie interesujące Cię daty).

Ponadto zapytanie jako całość może stać się znacznie prostsze.

SELECT
   cal.calendar_date   AS data_date,
   CASE WHEN prev_data.gap <= next_data.gap
        THEN prev_data.data_value
        ELSE COALESCE(next_data.data_value, prev_data.data_value)
   END
       AS data_value
FROM
    calendar   AS cal
OUTER APPLY
(
    SELECT TOP(1)
        data_date,
        data_value,
        DATEDIFF(DAY, data_date, cal.calendar_date)   AS gap
    FROM
        data_table
    WHERE
        data_date <= cal.calendar_date
    ORDER BY
        data_date DESC
)
   prev_data
OUTER APPLY
(
    SELECT TOP(1)
        data_date,
        data_value,
        DATEDIFF(DAY, cal.calendar_date, data_date)   AS gap
    FROM
        data_table
    WHERE
        data_date >  cal.calendar_date
    ORDER BY
        data_date ASC
)
   next_data
WHERE
   cal.calendar_date BETWEEN '2015-01-01' AND '2015-12-31'
;

EDYTUJ Odpowiedz na swój komentarz, podając inne wymagania

Aby zawsze uzyskać "powyższą wartość" jest łatwiejsze, a wstawienie tych wartości do tabeli jest wystarczająco łatwe...

INSERT INTO
    data_table
SELECT
   cal.calendar_date,
   prev_data.data_value
FROM
    calendar   AS cal
CROSS APPLY
(
    SELECT TOP(1)
        data_date,
        data_value
    FROM
        data_table
    WHERE
        data_date <= cal.calendar_date
    ORDER BY
        data_date DESC
)
   prev_data
WHERE
       cal.calendar_date BETWEEN '2015-01-01' AND '2015-12-31'
   AND cal.calendar_date <> prev_data.data_date
;

Uwaga: Możesz dodać WHERE prev_data.gap > 0 do większego zapytania powyżej, aby uzyskać tylko daty, które nie mają jeszcze danych.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przywracanie bazy danych programu SQL Server — nie powiodło się:38 (Osiągnięto koniec pliku.)

  2. Wykonywanie zadania SQL Server Agent z procedury składowanej i zwracanie wyniku zadania

  3. Jak mogę uzyskać sumę wielu wartości daty i godziny?

  4. Jak określić Like w kolumnie liczb całkowitych?

  5. if warunek w zapytaniu o aktualizację serwera sql