简体   繁体   中英

Combine Output of Queries in Pivot Table with PostgreSQL

Suppose I have a table called orders that looks like this:

id order date Orders_Wanted Orders_Given
1 2020-11-29 19:12:44.417 2 6
1 2020-11-29 20:12:44.417 2 6
1 2020-11-30 23:37:28.692 8 2
1 2020-11-30 23:37:28.692 2 6

How do I write a query that shows the count of orders_wanted - orders_given by hour broken down into two columns, one that counts positive results and one that counts negative results (a note that orders_wanted and orders_given are times, so that's why I am calculating orders_wanted - orders_given). I would also like to add a final column that calculates the percentage of total orders per hour that are positive (count_orders_positive/ (count_orders_negative + Count_orders_positive)).

The output of the query would look something like this:

week day hour count_orders_positive count_orders_negative Percentage_orders_positive
48 7 19 0 1 100%
48 7 20 0 1 100%
49 1 23 1 1 50%

So far I am able to get the bottom two results using these queries, but I don't know how to combine them.

SELECT  
extract (week from (order_date at time zone 'MST' at time zone 'UTC') ) as "week", 
extract (isodow from (order_date at time zone 'MST' at time zone 'UTC') ) as "day",
extract (hour from (order_date at time zone 'MST' at time zone 'UTC') ) as "hour",
Count (extract (hour from (order_date at time zone 'MST' at time zone 'UTC') )) as 
"count_orders_positive" 
from orders  
WHERE orders_wanted - orders_given >= 0
group by week, day, hour
order by week, day, hour;
week day hour count_orders_positive
49 1 23 1
SELECT
extract (week from (order_date at time zone 'MST' at time zone 'UTC') ) as "week", 
extract (isodow from (order_date at time zone 'MST' at time zone 'UTC') ) as "day",
extract (hour from (order_date at time zone 'MST' at time zone 'UTC') ) as "hour",
Count (extract (hour from (order_date at time zone 'MST' at time zone 'UTC') )) as 
"count_orders_negative" 
from orders  
WHERE orders_wanted - orders_given < 0
group by week, day, hour
order by week, day, hour;
week day hour count_orders_negative
48 7 19 1
48 7 20 1
49 1 23 1

You can do conditional aggregation. avg() comes handy to compute the percentage:

select  
    extract (week   from (order_date at time zone 'MST' at time zone 'UTC') ) as "week", 
    extract (isodow from (order_date at time zone 'MST' at time zone 'UTC') ) as "day",
    extract (hour   from (order_date at time zone 'MST' at time zone 'UTC') ) as "hour",
    count(*) filter (where orders_wanted - orders_given >= 0) as count_orders_positive,
    count(*) filter (where orders_wanted - orders_given <  0) as count_orders_negative,
    100 * avg((orders_wanted - orders_given >= 0)::int) as percent_orders_positive
from orders
group by week, day, hour
order by week, day, hour;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM