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

1つのSQLクエリで複数の時系列を生成するにはどうすればよいですか?

    解決策1.集計を使用した単純なクエリ。

    期待される結果を得るための最も簡単で最速の方法。 salesを解析するのは簡単です クライアントプログラム内の列。

    select item, string_agg(coalesce(sales, 0)::text, ',') sales
    from (
        select distinct item_id item, doy
        from generate_series (1, 10) doy  -- change 10 to given n
        cross join entry_daily
        ) sub
    left join entry_daily on item_id = item and day_of_year = doy
    group by 1
    order by 1;
    
     item |        sales         
    ------+----------------------
     A1   | 20,0,0,0,0,0,9,0,0,0
     A2   | 11,0,0,0,0,0,0,0,0,0
    (2 rows)
    

    解決策2.動的に作成されたビュー。

    array_agg()を使用したソリューション1に基づく string_agg()の代わりに 。この関数は、指定された数の列を持つビューを作成します。

    create or replace function create_items_view(view_name text, days int)
    returns void language plpgsql as $$
    declare
        list text;
    begin
        select string_agg(format('s[%s] "%s"', i::text, i::text), ',')
        into list
        from generate_series(1, days) i;
    
        execute(format($f$
            drop view if exists %s;
            create view %s as select item, %s
            from (
                select item, array_agg(coalesce(sales, 0)) s
                from (
                    select distinct item_id item, doy
                    from generate_series (1, %s) doy
                    cross join entry_daily
                    ) sub
                left join entry_daily on item_id = item and day_of_year = doy
                group by 1
                order by 1
            ) q
            $f$, view_name, view_name, list, days)
        );
    end $$;
    

    使用法:

    select create_items_view('items_view_10', 10);
    
    select * from items_view_10;
    
     item | 1  | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 
    ------+----+---+---+---+---+---+---+---+---+----
     A1   | 20 | 0 | 0 | 0 | 0 | 0 | 9 | 0 | 0 |  0
     A2   | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |  0
    (2 rows)
    

    ソリューション3.クロス集計。

    使いやすいですが、行の形式を定義する必要があるため、列の数が多いと非常に不快になります。

    create extension if not exists tablefunc;
    
    select * from crosstab (
        'select item_id, day_of_year, sales
        from entry_daily
        order by 1',
        'select i from generate_series (1, 10) i'
    ) as ct 
    (item_id text, "1" int, "2" int, "3" int, "4" int, "5" int, "6" int, "7" int, "8" int, "9" int, "10" int);
    
     item_id | 1  | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 
    ---------+----+---+---+---+---+---+---+---+---+----
     A1      | 20 |   |   |   |   |   | 9 |   |   |   
     A2      | 11 |   |   |   |   |   |   |   |   |   
    (2 rows)
    


    1. SSRS-式を使用したGroup_Concatと同等ですか?

    2. テキストファイルからOracleのテーブルへのデータのロード

    3. 祖父母列を参照するSQLネストサブクエリ

    4. SQLAlchemy、PostgreSQL、array_agg:array_aggからアイテムを選択する方法は?