-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDDL.sql
More file actions
214 lines (177 loc) · 5 KB
/
Copy pathDDL.sql
File metadata and controls
214 lines (177 loc) · 5 KB
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
CREATE TABLE categories(
category_id INT PRIMARY KEY,
category TEXT NOT NULL
);
CREATE TABLE book(
book_id INT PRIMARY KEY,
category_id INT NOT NULL REFERENCES Categories(category_id),
title TEXT NOT NULL,
upc TEXT UNIQUE,
product_type TEXT NOT NULL,
url TEXT UNIQUE,
description TEXT NOT NULL
);
CREATE TABLE book_price (
book_id INT REFERENCES book(book_id),
price REAL,
price_excl_tax REAL,
price_incl_tax REAL,
tax NUMERIC,
PRIMARY KEY (book_id)
);
CREATE TABLE book_availability (
book_id INT REFERENCES book(book_id),
disponibility BOOLEAN,
stock INT,
availability_info TEXT,
PRIMARY KEY (book_id)
);
CREATE TABLE book_review (
book_id INT REFERENCES book(book_id),
calification INT,
n_reviews INT,
PRIMARY KEY (book_id)
);
-- MODELO ESTRELLA --
CREATE TABLE dim_category (
category_id INT PRIMARY KEY,
category TEXT NOT NULL
);
CREATE TABLE dim_book (
book_id INT PRIMARY KEY,
title TEXT NOT NULL,
upc TEXT UNIQUE,
product_type TEXT NOT NULL,
url TEXT UNIQUE,
description TEXT NOT NULL
);
CREATE TABLE dim_date (
date_key INT PRIMARY KEY,
date DATE NOT NULL,
year INT,
month INT,
day INT
);
CREATE TABLE fact_table (
book_id INT NOT NULL REFERENCES dim_book(book_id),
category_id INT NOT NULL REFERENCES dim_category(category_id),
date_key INT NOT NULL REFERENCES dim_date(date_key),
price REAL,
price_excl_tax REAL,
price_incl_tax REAL,
tax REAL,
stock INT,
disponibility BOOLEAN,
calification INT,
n_reviews INT,
PRIMARY KEY (book_id)
);
DROP TABLE fact_table
INSERT INTO dim_category (category_id, category)
SELECT c.category_id, c.category
FROM categories c
SELECT * FROM dim_category
INSERT INTO dim_book (book_id, title, upc, product_type, url, description)
SELECT b.book_id, b.title, b.upc, b.product_type, b.url, b.description
FROM book b
SELECT * FROM dim_book
INSERT INTO dim_date (date_key, date, year, month, day)
VALUES (
TO_CHAR(CURRENT_DATE, 'YYYYMMDD')::INT,
CURRENT_DATE,
EXTRACT(YEAR FROM CURRENT_DATE)::INT,
EXTRACT(MONTH FROM CURRENT_DATE)::INT,
EXTRACT(DAY FROM CURRENT_DATE)::INT
)
SELECT * FROM dim_date
INSERT INTO fact_table (
book_id, category_id, date_key,
price, price_excl_tax, price_incl_tax, tax,
stock, disponibility, calification, n_reviews
)
SELECT
db.book_id,
db.category_id,
TO_CHAR(CURRENT_DATE, 'YYYYMMDD')::INT AS date_key,
bp.price, bp.price_excl_tax, bp.price_incl_tax, bp.tax,
ba.stock, ba.disponibility,
br.calification, br.n_reviews
FROM book db
LEFT JOIN book_price bp ON bp.book_id = db.book_id
LEFT JOIN book_availability ba ON ba.book_id = db.book_id
LEFT JOIN book_review br ON br.book_id = db.book_id
SELECT * FROM fact_table
-- CONSULTAS --
-- ¿Cuántas categorías de libros se tienen?
SELECT COUNT(*) AS num_categorias FROM dim_category
-- ¿Cuántos libros hay por categoría hay?
SELECT dc.category , COUNT(*) AS libros_x_categoria
FROM dim_category dc
LEFT JOIN fact_table f ON f.category_id = dc.category_id
GROUP BY dc.category
ORDER BY libros_x_categoria DESC
-- ¿Cuál es el libro más caro?
SELECT b.title, ft.price
FROM fact_table ft
INNER JOIN dim_book b ON ft.book_id = b.book_id
ORDER BY ft.price DESC LIMIT 1
-- ¿Hay algún libro que esté en dos categorías?
SELECT b.book_id, COUNT(DISTINCT ft.category_id) AS categorias_distintas
FROM dim_book b
JOIN fact_table ft
ON b.book_id = ft.book_id
GROUP BY b.book_id
HAVING COUNT(DISTINCT ft.category_id) > 1;
-- ¿Cuál es el libro más barato por categoría?
WITH ranked AS(
SELECT c.category, b.title, ft.price, DENSE_RANK() OVER (PARTITION BY category ORDER BY price ASC NULLS LAST) AS rnk
FROM fact_table ft
INNER JOIN dim_book b ON ft.book_id = b.book_id
INNER JOIN dim_category c ON ft.category_id = c.category_id
)
SELECT category, title, price
FROM ranked
WHERE rnk = 1
-- ¿Cuánto más caro o barato es cada libro con respecto al promedio de su categoría?
WITH base AS (
SELECT c.category, b.title, f.price
FROM fact_table f
JOIN dim_book b ON b.book_id = f.book_id
JOIN dim_category c ON c.category_id = f.category_id
),
stats AS (
SELECT category, AVG(price) AS avg_price
FROM base
GROUP BY category
)
SELECT
a.category,
a.title,
a.price,
s.avg_price,
(a.price - s.avg_price) AS delta_price
FROM base a
JOIN stats s USING (category)
ORDER BY a.category, delta_price DESC NULLS LAST, a.title;
-- Asumiendo que se venden todos los libros que están en stock en este momento
-- ¿Cuál es el libro que daría más ingresos por categoría?
WITH revenue AS (
SELECT
c.category,
b.title,
f.price,
f.stock,
(f.price * COALESCE(f.stock, 0))::numeric AS revenue
FROM fact_table f
JOIN dim_book b ON b.book_id = f.book_id
JOIN dim_category c ON c.category_id = f.category_id
),
ranked AS (
SELECT *,
RANK() OVER (PARTITION BY category ORDER BY revenue DESC NULLS LAST) AS rnk
FROM revenue
)
SELECT category, title, price, stock, revenue
FROM ranked
WHERE rnk = 1
ORDER BY category, revenue DESC NULLS LAST;