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

PostgreSQLクエリを使用して毎日の統計で時系列を生成する

    手順1.値NEW=1、ACTIVE =1、DONE =2:

    を使用して、各注文の状態の累積合計を計算します。
    select 
        order_id, timestamp::date as day, 
        sum(case new_state when 'DONE' then 2 else 1 end) over w as state
    from order_state_history h
    join orders o on o.id = h.order_id
    where o.type = 1
    window w as (partition by order_id order by timestamp)
    
     order_id |    day     | state 
    ----------+------------+-------
        10000 | 2001-01-01 |     1
        10000 | 2001-01-02 |     2
        10000 | 2001-01-03 |     4
        10001 | 2001-01-02 |     1
        10004 | 2001-01-05 |     1
        10004 | 2001-01-10 |     3
    (6 rows)
    

    ステップ2.ステップ1の状態に基づいて各次数の遷移行列を計算します(2はNEW-> ACTIVE、3はNEW-> DONE、4はACTIVE-> DONEを意味します):

    select 
        order_id, day, state,
        case when state = 1 then 1 when state = 2 or state = 3 then -1 else 0 end as new,
        case when state = 2 then 1 when state = 4 then -1 else 0 end as active,
        case when state > 2 then 1 else 0 end as done
    from (
        select 
            order_id, timestamp::date as day, 
            sum(case new_state when 'DONE' then 2 else 1 end) over w as state
        from order_state_history h
        join orders o on o.id = h.order_id
        where o.type = 1
        window w as (partition by order_id order by timestamp)
        ) s
    
     order_id |    day     | state | new | active | done 
    ----------+------------+-------+-----+--------+------
        10000 | 2001-01-01 |     1 |   1 |      0 |    0
        10000 | 2001-01-02 |     2 |  -1 |      1 |    0
        10000 | 2001-01-03 |     4 |   0 |     -1 |    1
        10001 | 2001-01-02 |     1 |   1 |      0 |    0
        10004 | 2001-01-05 |     1 |   1 |      0 |    0
        10004 | 2001-01-10 |     3 |  -1 |      0 |    1
    (6 rows)
    

    ステップ3.一連の日の各状態の累積合計を計算します。

    select distinct
        day::date,
        sum(new) over w as new,
        sum(active) over w as active,
        sum(done) over w as done
    from generate_series('2001-01-01'::date, '2001-01-10', '1d'::interval) day
    left join (
        select 
            order_id, day, state,
            case when state = 1 then 1 when state = 2 or state = 3 then -1 else 0 end as new,
            case when state = 2 then 1 when state = 4 then -1 else 0 end as active,
            case when state > 2 then 1 else 0 end as done
        from (
            select 
                order_id, timestamp::date as day, 
                sum(case new_state when 'DONE' then 2 else 1 end) over w as state
            from order_state_history h
            join orders o on o.id = h.order_id
            where o.type = 1
            window w as (partition by order_id order by timestamp)
            ) s
        ) s
    using(day)
    window w as (order by day)
    order by 1
    
        day     | new | active | done 
    ------------+-----+--------+------
     2001-01-01 |   1 |      0 |    0
     2001-01-02 |   1 |      1 |    0
     2001-01-03 |   1 |      0 |    1
     2001-01-04 |   1 |      0 |    1
     2001-01-05 |   2 |      0 |    1
     2001-01-06 |   2 |      0 |    1
     2001-01-07 |   2 |      0 |    1
     2001-01-08 |   2 |      0 |    1
     2001-01-09 |   2 |      0 |    1
     2001-01-10 |   1 |      0 |    2
    (10 rows)   
    



    1. 番号を省略番号にフォーマットする

    2. Selectステートメントのケース

    3. Mysql Codeigniter Active Record-where_inクエリを実行して、正しい順序の結果を返すにはどうすればよいですか?

    4. MySQLエラー1349何が欠けていますか?