sql >> Database >  >> RDS >> Sqlserver

zoek de ontbrekende gegevens voor de werkdagen en vul de rij met de waarden van de dichtstbijzijnde datum

Voor dit soort zoekopdrachten profiteert u van aanzienlijke prestatievoordelen door een kalendertabel te maken met elke datum die u ooit zult moeten testen. (Als u bekend bent met de term 'dimensietabellen', is dit slechts zo'n tabel om elke interessante datum op te sommen.)

Ook kan de vraag als geheel aanzienlijk eenvoudiger worden.

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

BEWERKEN Reageer op je opmerking met een andere eis

Het is gemakkelijker om altijd "de waarde hierboven" te krijgen, en om die waarden in een tabel in te voegen is eenvoudig genoeg...

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
;

Opmerking: U kunt WHERE prev_data.gap > 0 . toevoegen naar de grotere zoekopdracht hierboven om alleen datums te krijgen die nog geen gegevens bevatten.



  1. Waarom bespaart SQL Server DATETIME-type tijd in tikken van 1/300 van een seconde?

  2. Maak een MySQL-verbinding in Playframework met slick

  3. Postgres - hoe rijen met 0-tellingen te retourneren voor ontbrekende gegevens?

  4. Hoe verificatie uitvoeren in node.js die ik vanaf mijn website kan gebruiken?