sql >> データベース >  >> RDS >> Sqlserver

営業日の不足しているエントリを見つけて、最も近い日付の値で行を埋めます

    これらのタイプのクエリでは、テストする必要があるすべての日付を含むカレンダー テーブルを作成すると、パフォーマンスが大幅に向上します。 (「ディメンション テーブル」という用語に精通している場合、これは関心のあるすべての日付を列挙するテーブルの 1 つにすぎません)

    また、クエリ全体が大幅に簡素化されます。

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

    編集 別の要件でコメントに返信してください

    常に「上の値」を取得する方が簡単で、それらの値をテーブルに挿入するのは簡単です...

    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
    ;
      

    注: WHERE prev_data.gap > 0 を追加できます 上記のより大きなクエリに、まだデータがない日付のみを取得します。



    1. 改行文字をhtmlに変換するSQLクエリ

    2. Javaを使用したAES_ENCRYPTおよびAES_DECRYPT

    3. getNextExceptionを呼び出して、原因を確認します。Hibernate/JPAに例外のDBサーバーメッセージを表示させる方法

    4. MySQLの2列のタイムスタンプのデフォルトのNOW値ERROR1067