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

時間の経過とともに不足しているギャップを埋め、最後の非 null 値を取得するための SQL クエリ

    SQL Fiddle を作成しました

    基本的に、ワーク テーブル @Months を作成してから、データ セット内のすべての年をクロス結合します。これにより、すべての年のすべての月の完全なリストが作成されます。次に、例で提供されているテスト データ (TEST という名前のテーブル - スキーマについては SQL フィドルを参照) をこのリストに戻して、それらがある月の値を含む完全なリストを提供します。克服すべき次の問題は、今月に値がない場合に先月の値を使用することでした。そのために、相関サブクエリを使用しました。つまり、値を持つ行の最大ランクに一致する場合にのみ、tblValues を結合しました。これにより、完全な結果セットが得られます!

    年\月でフィルタリングする場合は、これを WHERE 句の最後の Order By の直前に追加できます。

    お楽しみください!

    テスト スキーマ

    CREATE TABLE TEST( Month tinyint, Year int, Value int)
    
    INSERT INTO TEST(Month, Year, Value)
    VALUES
       (1,2013,100),
       (4,2013,101),
       (8,2013,102),
       (2,2014,103),
       (4,2014,104)
    

    クエリ

    DECLARE @Months Table(Month tinyint)
    Insert into @Months(Month)Values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
    
    
    With tblValues as (
      select Rank() Over (ORDER BY y.Year, m.Month) as [Rank], 
              m.Month, 
              y.Year, 
              t.Value
      from @Months m
      CROSS JOIN ( Select Distinct Year from Test ) y
      LEFT JOIN Test t on t.Month = m.Month and t.Year = y.Year
      )
    Select t.Month, t.Year, COALESCE(t.Value, t1.Value) as Value
    from tblValues t
    left join tblValues t1 on t1.Rank = (
                Select Max(tmax.Rank)
                From tblValues tmax 
                Where tmax.Rank < t.Rank AND tmax.Value is not null)
    
    Order by t.Year, t.Month
    



    1. 2018年のMySQL:8.0およびその他の所見の内容

    2. 各部門から最大SALのEMPを選択します

    3. OracleのREMAINDER()関数

    4. Mysqlの無関係なテーブルから外部キー制約を適用するにはどうすればよいですか?