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

年の配列を年の範囲として返す

    SELECT id, string_agg(year_range, ', ') AS year_ranges
    FROM (
       SELECT id, CASE WHEN count(*) > 1
                   THEN min(year)::text || '-' ||  max(year)::text 
                   ELSE min(year)::text
                  END AS year_range
       FROM  (
          SELECT *, row_number() OVER (ORDER BY id, year) - year AS grp
          FROM  (
             SELECT id, unnest(years) AS year
             FROM  (VALUES (2::int, '{1999,2000,2010,2011,2012}'::int[])
                          ,(3,      '{1990,1991,2007}')
                   ) AS tbl(id, years)
             ) sub1
          ) sub2
       GROUP  BY id, grp
       ORDER  BY id, min(year)
       ) sub3
    GROUP  BY id
    ORDER  BY id
    

    正確に生成します 望ましい結果。

    varcharの配列を処理する場合(varchar[]int[]にキャストするだけです 、続行する前に。そのためには完全に合法的な形式のようです:

    years::int[]
    

    内側の副選択を、生産的なコードのソーステーブルの名前に置き換えます。

     FROM  (VALUES (2::int, '{1999,2000,2010,2011,2012}'::int[])
                  ,(3,      '{1990,1991,2007}')
           ) AS tbl(id, years)
    

    ->

    FROM  tbl
    

    自然に昇順の数字を扱っているので (年)ショートカットを使用して、連続する年のグループを形成できます(範囲を形成します)。行番号(年順)から年自体を減算します。連続する年については、行番号と年の両方が1ずつ増加し、同じgrpを生成します。 番号。それ以外の場合は、新しい範囲が始まります。

    ウィンドウ関数の詳細 マニュアルのこちら およびこちら 。

    この場合、plpgsql関数はさらに高速になる可能性があります。テストする必要があります。これらの関連する回答の例:
    連続した繰り返し/重複の順序付けられた数
    ROW_NUMBER()に予期しない値が表示される



    1. Linux上の.NETをODBCデータソースに接続する

    2. 再帰関数をビューに変換する

    3. MySQLの条件付き値チェックで制約する

    4. SQLプラクティスのためにOracleExpressEditionをインストールする方法