forked from tulski-s/full_stack_de
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dashboard_queries.sql
171 lines (158 loc) · 7.06 KB
/
dashboard_queries.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
-- orders value: realized vs. pending vs. lost
SELECT DATE_TRUNC('month', place_date)
,SUM(CASE WHEN grp = 'realized' THEN total_order_price ELSE 0 END) AS realized_value
,SUM(CASE WHEN grp = 'pending' THEN total_order_price ELSE 0 END) AS pending_value
,SUM(CASE WHEN grp = 'lost' THEN total_order_price ELSE 0 END) AS lost_value
FROM (SELECT CASE WHEN st.name IN ('PAID', 'SHIPPED') THEN 'realized'
WHEN st.name IN ('PURCHASE ORDER') THEN 'pending'
WHEN st.name IN ('REFUNDED', 'CLOSED') THEN 'lost'
END AS grp
, total_order_price
, place_date
FROM dwh.f_order f
INNER JOIN dwh.d_status st ON st.status_sk = f.status_sk) d
WHERE DATE_TRUNC('month', place_date)::DATE BETWEEN '2010-01-01' AND '2017-10-01'
GROUP BY DATE_TRUNC('month', place_date)
ORDER BY DATE_TRUNC('month', place_date) ASC
;
-- lost orders (returns and cancelation) value ratio
SELECT date, (lost/rest)*100 AS lost_orders_val_ratio
,30 - (lost/rest)*100 AS dev_from_goal
,0 AS goal
FROM (SELECT DATE_TRUNC('month', place_date) AS date
,SUM(CASE WHEN st.name IN ('REFUNDED', 'CLOSED') THEN total_order_price ELSE 0 END) AS lost
,SUM(CASE WHEN st.name NOT IN ('REFUNDED', 'CLOSED') THEN total_order_price ELSE 0 END) AS rest
FROM dwh.f_order f
INNER JOIN dwh.d_status st ON st.status_sk = f.status_sk
GROUP BY DATE_TRUNC('month', place_date)) d
ORDER BY date
;
-- sales by quarter
SELECT d.year_actual, d.quarter_name, SUM(total_order_price)
FROM dwh.f_order f
INNER JOIN dwh.d_date d ON d.date_actual = f.place_date
WHERE status_sk IN (2,3) AND d.year_actual >= 2016
GROUP BY d.quarter_name, d.year_actual
ORDER BY d.year_actual, d.quarter_name ASC
;
-- top sales by subtypes last 30 days
SELECT p.subtype, SUM(fl.quantity*p.price)
FROM dwh.f_order_line fl
INNER JOIN dwh.d_product p ON p.product_sk = fl.product_sk
INNER JOIN dwh.f_order f ON f.order_id = fl.order_id
INNER JOIN dwh.d_date d ON d.date_actual = f.place_date
WHERE status_sk IN (2,3) AND d.date_actual >= '2017-11-01'::DATE - interval '30 days'
GROUP BY p.subtype
ORDER BY SUM(fl.quantity*p.price) DESC
LIMIT 10
;
-- top sales by product last 30 days
SELECT p.name, SUM(fl.quantity*p.price)
FROM dwh.f_order_line fl
INNER JOIN dwh.d_product p ON p.product_sk = fl.product_sk
INNER JOIN dwh.f_order f ON f.order_id = fl.order_id
INNER JOIN dwh.d_date d ON d.date_actual = f.place_date
WHERE status_sk IN (2,3) AND d.date_actual >= '2017-11-01'::DATE - interval '30 days'
GROUP BY p.name
ORDER BY SUM(fl.quantity*p.price) DESC
LIMIT 10
;
-- top countries
SELECT a.country, SUM(f.total_order_price)
FROM dwh.f_order f
INNER JOIN dwh.d_address a ON f.address_sk = a.address_sk
INNER JOIN dwh.d_date d ON d.date_actual = f.place_date
WHERE status_sk IN (2,3) AND d.date_actual >= '2017-11-01'::DATE - interval '30 days'
GROUP BY a.country
ORDER BY SUM(f.total_order_price) DESC
LIMIT 10
;
-- no of customers per quarter
SELECT d.year_actual, d.quarter_name, COUNT(DISTINCT customer_sk)
FROM dwh.f_order f
INNER JOIN dwh.d_date d ON d.date_actual = f.place_date
WHERE status_sk IN (2,3) AND d.year_actual >= 2016
GROUP BY d.quarter_name, d.year_actual
ORDER BY d.year_actual, d.quarter_name ASC
;
-- sales month-over-month growth: (This month - Last month) / (Last month)
SELECT date, sales AS cur_month, LAG(sales) OVER (ORDER BY date) AS prev_month
, ROUND((sales- LAG(sales) OVER (ORDER BY date))/ LAG(sales) OVER (ORDER BY date),2) AS mom_growth
FROM (SELECT DATE_TRUNC('month', place_date)::DATE AS date, SUM(total_order_price) AS sales
FROM dwh.f_order f
WHERE DATE_TRUNC('month', place_date)::DATE BETWEEN '2010-01-01' AND '2017-10-01'
AND status_sk IN (2,3)
GROUP BY DATE_TRUNC('month', place_date)::DATE
ORDER BY DATE_TRUNC('month', place_date)::DATE) x
;
-- KPIs
SELECT d.date_actual
,f_sls.sales AS sales
,f_flmt.avg_fulfilment AS avg_fulfilment
,f_orsz.avg_order AS avg_order_val
,f_ldev.dev_from_goal AS avg_lost_dev_from_goal
FROM dwh.d_date d
INNER JOIN (SELECT place_date ,AVG(paid_date-place_date)::INT AS avg_fulfilment
FROM dwh.f_order f
WHERE status_sk = 3
GROUP BY place_date) f_flmt
ON f_flmt.place_date = d.date_actual
INNER JOIN (SELECT place_date
,ROUND(AVG(total_order_price), 2) AS avg_order
FROM dwh.f_order
GROUP BY place_date) f_orsz
ON f_orsz.place_date = d.date_actual
INNER JOIN (SELECT d.date, ROUND(30 - (lost/d.all)*100, 2) AS dev_from_goal
FROM (SELECT place_date AS date
,SUM(CASE WHEN st.name IN ('REFUNDED', 'CLOSED') THEN total_order_price ELSE 0 END) AS lost
,SUM(total_order_price) AS all
FROM dwh.f_order f
INNER JOIN dwh.d_status st ON st.status_sk = f.status_sk
GROUP BY place_date) d) f_ldev
ON f_ldev.date = d.date_actual
INNER JOIN (SELECT place_date, SUM(total_order_price) AS sales
FROM dwh.f_order
WHERE status_sk IN (2,3)
GROUP BY place_date) f_sls
ON f_sls.place_date = d.date_actual
ORDER BY d.date_actual ASC
;
-- sales by quarter
SELECT d.quarter_name||'/'||d.year_actual AS quarter, SUM(total_order_price) AS total_sales
FROM dwh.f_order f
INNER JOIN dwh.d_date d ON d.date_actual = f.place_date
WHERE (d.year_actual = 2017 AND d.quarter_name IN ('Q1', 'Q2', 'Q3') OR d.year_actual = 2016 AND d.quarter_name = 'Q3')
AND status_sk IN (2,3)
GROUP BY d.quarter_name, d.year_actual
ORDER BY d.year_actual, d.quarter_name
;
-- unique customers by quarter
SELECT d.quarter_name||'/'||d.year_actual AS quarter, COUNT(DISTINCT customer_sk) AS unique_customers_cnt
FROM dwh.f_order f
INNER JOIN dwh.d_date d ON d.date_actual = f.place_date
WHERE (d.year_actual = 2017 AND d.quarter_name IN ('Q1', 'Q2', 'Q3') OR d.year_actual = 2016 AND d.quarter_name = 'Q3')
AND status_sk IN (2,3)
GROUP BY d.quarter_name, d.year_actual
ORDER BY d.year_actual, d.quarter_name
;
/*
top X customers table with: total_orders_val, avr_order_val, no_orders, total_purchased_items
only some statuses are taken into accountfd
*/
SELECT cust.first_name
,cust.last_name
,SUM(total_order_price) AS total_orders_val
,ROUND(AVG(total_order_price),2) AS avg_order_val
,COUNT(*) AS total_no_orders
,MAX(oli.prods_count) AS total_purchased_items
FROM dwh.f_order f
INNER JOIN dwh.d_customer cust ON cust.customer_sk = f.customer_sk
INNER JOIN dwh.d_status st ON st.status_sk = f.status_sk
INNER JOIN (SELECT customer_sk, SUM(quantity) AS prods_count
FROM dwh.f_order_line ol
INNER JOIN dwh.f_order o ON o.order_id = ol.order_id
GROUP BY customer_sk) oli ON oli.customer_sk = f.customer_sk
WHERE st.name IN ('PURCHASE ORDER', 'PAID', 'SHIPPED')
GROUP BY cust.customer_sk
ORDER BY SUM(total_order_price) DESC
;