DatabaseCreation: views.2.sql

File views.2.sql, 8.7 KB (added by 231017, 9 days ago)
Line 
1-- view #1 - for each user get followers and following
2
3CREATE OR REPLACE VIEW user_follow_info AS
4(
5 WITH user_followers AS (SELECT followed_user_id AS user_id, count(followed_user_id) AS followers
6 FROM follows
7 GROUP BY followed_user_id),
8 user_follows AS (SELECT follower_user_id AS user_id, count(followed_user_id) AS following
9 FROM follows
10 GROUP BY follower_user_id)
11 SELECT uf1.user_id,
12 username,
13 coalesce(followers, 0) AS followers,
14 coalesce(following, 0) AS following
15 FROM user_follows uf1
16 LEFT JOIN user_followers uf2 ON uf1.user_id = uf2.user_id
17 LEFT JOIN users u ON u.id = uf1.user_id
18 -- ORDER BY followers DESC
19);
20
21-- view #2 - most active users - users with the most streams in the last 30 days
22
23CREATE OR REPLACE VIEW user_activity_last_30_days AS
24(
25 WITH streams_per_user AS (SELECT ss.user_id, COUNT(ss.song_id) AS stream_count
26 FROM song_streams ss
27 WHERE ss.streamed_at BETWEEN current_date - 30 and now()
28 GROUP BY ss.user_id)
29 SELECT u.username, spu.*
30 FROM users u
31 JOIN streams_per_user spu ON u.id = spu.user_id
32 -- ORDER BY stream_count DESC
33);
34
35-- view #3 - average review grade and number of review per song
36
37CREATE OR REPLACE VIEW song_average_grade AS
38(
39 WITH avg_grade AS (SELECT song_id,
40 AVG(r.grade) AS avg_grade,
41 COUNT(r.grade) AS num_reVIEWs
42 FROM reVIEWs r
43 GROUP BY r.song_id)
44 SELECT s.id AS song_id,
45 s.title AS song_title,
46 u.username AS released_by,
47 u.id AS user_id,
48 ag.avg_grade,
49 ag.num_reVIEWs
50 FROM songs s
51 JOIN avg_grade ag ON ag.song_id = s.id
52 JOIN users u ON u.id = s.owner_artist_id
53 ORDER BY avg_grade DESC, num_reviews DESC
54);
55
56
57-- view #4 - streams per artist in the last 30 days
58
59CREATE OR REPLACE VIEW artist_popularity_last_30_days AS
60WITH streams_count AS (
61 SELECT ss.song_id, COUNT(*) AS cnt
62 FROM song_streams ss
63 WHERE ss.streamed_at >= CURRENT_TIMESTAMP - INTERVAL '30 days'
64 GROUP BY ss.song_id
65),
66artist_listens AS (
67 SELECT
68 a.id AS artist_id,
69 a.display_name AS artist_display_name,
70 COALESCE(SUM(sc.cnt), 0) AS total_listens
71 FROM artists a
72 LEFT JOIN songs s ON s.owner_artist_id = a.id
73 LEFT JOIN streams_count sc ON sc.song_id = s.id
74 GROUP BY a.id, a.display_name
75)
76SELECT
77 ROW_NUMBER() OVER (ORDER BY total_listens DESC) AS rank,
78 artist_id,
79 artist_display_name,
80 total_listens
81FROM artist_listens;
82
83
84-- view #5 - most popular songs in the last 30 days
85
86CREATE OR REPLACE VIEW most_popular_songs_last_30_days AS
87WITH stream_counts AS (
88 SELECT
89 song_id,
90 COUNT(*) AS total_streams
91 FROM song_streams
92 WHERE streamed_at >= CURRENT_TIMESTAMP - INTERVAL '30 days'
93 GROUP BY song_id
94)
95SELECT
96 ROW_NUMBER() OVER (ORDER BY sc.total_streams DESC) AS rank,
97 s.id AS song_id,
98 s.title AS song_title,
99 a.display_name AS artist_display_name,
100 s.visibility AS song_visibility,
101 l.name AS label_name,
102 sc.total_streams
103FROM stream_counts sc
104JOIN songs s ON s.id = sc.song_id
105JOIN artists a ON s.owner_artist_id = a.id
106LEFT JOIN labels l ON l.id = s.published_by_label_id;
107
108
109-- view #6 - label's artists information
110
111CREATE OR REPLACE VIEW label_artists_info AS
112SELECT
113 l.name AS label_name,
114 a.display_name AS artist_display_name,
115 COUNT(DISTINCT s.id) AS songs,
116 COUNT(DISTINCT f.follower_user_id) AS followers
117FROM labels l
118JOIN artist_labels al ON al.label_id = l.id
119JOIN artists a ON a.id = al.artist_id
120LEFT JOIN songs s ON s.owner_artist_id = a.id
121LEFT JOIN follows f ON f.followed_user_id = a.user_id
122GROUP BY l.name, a.id, a.display_name
123ORDER BY l.name;
124
125
126-- view #7 - song details
127
128CREATE OR REPLACE VIEW songs_details AS
129WITH stream_counts AS (
130 SELECT
131 song_id,
132 COUNT(*) AS streams
133 FROM song_streams
134 GROUP BY song_id
135),
136playlist_counts AS (
137 SELECT
138 song_id,
139 COUNT(*) AS saved_in_playlists
140 FROM playlist_tracks
141 GROUP BY song_id
142)
143SELECT
144 s.title AS title,
145 a.display_name AS artist_name,
146 COALESCE(l.name, 'SOLO') AS label_name,
147 COALESCE(sc.streams, 0) AS streams,
148 COALESCE(alb.title, 'SINGLE') AS album_title,
149 COALESCE(pc.saved_in_playlists, 0) AS saved_in_playlists,
150 sag.num_reviews,
151 sag.avg_grade
152FROM songs s
153LEFT JOIN artists a ON a.id = s.owner_artist_id
154LEFT JOIN artist_labels al ON al.artist_id = a.id
155LEFT JOIN labels l ON l.id = al.label_id
156LEFT JOIN album_tracks at ON at.song_id = s.id
157LEFT JOIN albums alb ON alb.id = at.album_id
158LEFT JOIN stream_counts sc ON sc.song_id = s.id
159LEFT JOIN playlist_counts pc ON pc.song_id = s.id
160LEFT JOIN song_average_grade_mv sag ON sag.song_id = s.id;
161
162
163
164
165
166-- view #8 - streams history
167
168CREATE OR REPLACE VIEW streams_history AS
169SELECT
170 u.id AS user_id,
171 u.username,
172 s.id AS song_id,
173 s.title,
174 ss.streamed_at,
175 ps.listened_ms
176FROM users u
177JOIN song_streams ss ON ss.user_id = u.id
178JOIN songs s ON s.id = ss.song_id
179JOIN playback_sessions ps ON ps.id = ss.playback_session_id;
180
181
182
183
184
185-- MATERIALIZED VIEWS FOR OPTIMIZATION
186
187DROP VIEW artist_popularity_last_30_days;
188DROP VIEW most_popular_songs_last_30_days;
189DROP VIEW songs_details;
190DROP VIEW song_average_grade_mv;
191
192-- view #3
193
194DROP MATERIALIZED VIEW IF EXISTS song_average_grade_mv CASCADE;
195
196CREATE MATERIALIZED VIEW song_average_grade_mv AS
197SELECT s.id AS song_id,
198 s.title AS song_title,
199 u.username AS released_by,
200 u.id AS user_id,
201 ag.avg_grade,
202 ag.num_reviews
203FROM (SELECT song_id,
204 AVG(grade) AS avg_grade,
205 COUNT(grade) AS num_reviews
206 FROM reviews
207 GROUP BY song_id) ag
208JOIN songs s ON s.id = ag.song_id
209JOIN users u ON u.id = s.owner_artist_id;
210
211-- view #4
212
213CREATE MATERIALIZED VIEW artist_popularity_last_30_days_mv AS
214WITH streams_count AS (
215 SELECT ss.song_id, COUNT(*) AS cnt
216 FROM song_streams ss
217 WHERE ss.streamed_at >= CURRENT_TIMESTAMP - INTERVAL '30 days'
218 GROUP BY ss.song_id
219),
220artist_listens AS (
221 SELECT
222 a.id AS artist_id,
223 a.display_name AS artist_display_name,
224 COALESCE(SUM(sc.cnt), 0) AS total_listens
225 FROM artists a
226 LEFT JOIN songs s ON s.owner_artist_id = a.id
227 LEFT JOIN streams_count sc ON sc.song_id = s.id
228 GROUP BY a.id, a.display_name
229)
230SELECT
231 ROW_NUMBER() OVER (ORDER BY total_listens DESC) AS rank,
232 artist_id,
233 artist_display_name,
234 total_listens
235FROM artist_listens;
236
237
238
239-- view #5
240
241create or replace view most_popular_songs_last_30_days_mv as
242with stream_counts as (
243 select
244 song_id,
245 count(*) as total_streams
246 from song_streams
247 where streamed_at >= current_timestamp - interval '30 days'
248 group by song_id
249)
250select
251 row_number() over (order by sc.total_streams desc) as rank,
252 s.id as song_id,
253 s.title as song_title,
254 a.display_name as artist_display_name,
255 s.visibility as song_visibility,
256 l.name as label_name,
257 sc.total_streams
258from stream_counts sc
259join songs s on s.id = sc.song_id
260join artists a on s.owner_artist_id = a.id
261left join labels l on l.id = s.published_by_label_id;
262
263
264
265-- view #7
266
267CREATE MATERIALIZED VIEW song_stream_counts_mv AS
268SELECT
269 song_id,
270 COUNT(*) AS streams
271FROM song_streams
272GROUP BY song_id;
273
274
275CREATE MATERIALIZED VIEW song_playlist_counts_mv AS
276SELECT
277 song_id,
278 COUNT(*) AS saved_in_playlists
279FROM playlist_tracks
280GROUP BY song_id;
281
282
283CREATE OR REPLACE VIEW songs_details_mvs AS
284SELECT
285 s.title AS title,
286 a.display_name AS artist_name,
287 COALESCE(l.name, 'SOLO') AS label_name,
288 COALESCE(sc.streams, 0) AS streams,
289 COALESCE(alb.title, 'SINGLE') AS album_title,
290 COALESCE(pc.saved_in_playlists, 0) AS saved_in_playlists,
291 sag.num_reviews,
292 ROUND(sag.avg_grade, 2) AS avg_grade
293FROM songs s
294LEFT JOIN artists a ON a.id = s.owner_artist_id
295LEFT JOIN artist_labels al ON al.artist_id = a.id
296LEFT JOIN labels l ON l.id = al.label_id
297LEFT JOIN album_tracks at ON at.song_id = s.id
298LEFT JOIN albums alb ON alb.id = at.album_id
299LEFT JOIN song_stream_counts_mv sc ON sc.song_id = s.id
300LEFT JOIN song_playlist_counts_mv pc ON pc.song_id = s.id
301LEFT JOIN song_average_grade_mv sag ON sag.song_id = s.id;