sql >> Databasteknik >  >> RDS >> Sqlserver

hitta de saknade uppgifterna för arbetsdagarna och fyll raden med värdena från närmaste datum

För dessa typer av frågor får du betydande prestandafördelar genom att skapa en kalendertabell som innehåller alla datum du någonsin kommer att behöva testa. (Om du är bekant med termen "dimensionstabeller" är detta bara en sådan tabell för att räkna upp varje intressedatum.)

Dessutom kan frågan som helhet bli betydligt enklare.

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'
;

REDIGERA Svara på din kommentar med ett annat krav

Att alltid få "värdet ovan" är lättare, och att infoga dessa värden i en tabell är tillräckligt enkelt...

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
;

Obs! Du kan lägga till WHERE prev_data.gap > 0 till den större frågan ovan för att bara få datum som inte redan har data.



  1. Oracle föredragna kolumner längder

  2. Php 5.3 magick citat gpc

  3. Översätt denna MySQL-fråga till PyGreSQL

  4. lagra flera kryssrutor i databasen med php och mysql