sql >> Database >  >> RDS >> PostgreSQL

Genereer tijdreeksen met dagelijkse statistieken met behulp van een PostgreSQL-query

Stap 1. Bereken een cumulatieve som van de status voor elke bestelling, met behulp van de waarden NIEUW =​​1, ACTIEF =1, KLAAR =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)

Stap 2. Bereken een overgangsmatrix voor elke bestelling op basis van de toestanden uit stap 1 (2 betekent NIEUW->ACTIEF, 3 betekent NIEUW->GEREED, 4 betekent ACTIEF->GEREED):

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)

Stap 3. Bereken een cumulatieve som van elke staat voor een reeks dagen:

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. Slaapproblemen met Auto Increment ID MYSQL 5

  2. Zoek de dichtstbijzijnde datum in SQL Server

  3. mysql.connector geeft niet de laatste databasestatus in Python

  4. oracle connect door meerdere ouders