DatabaseCreation: views.sql

File views.sql, 4.3 KB (added by 231017, 20 hours ago)
Line 
1DROP VIEW user_follow_info;
2DROP VIEW user_activity_last_30_days;
3DROP VIEW song_average_grade;
4
5-- view #1 - for each user get followers and following
6create or replace view user_follow_info as
7(
8 with user_followers as (select followed_user_id as user_id, count(followed_user_id) as followers
9 from follows
10 group by followed_user_id),
11 user_follows as (select follower_user_id as user_id, count(followed_user_id) as following
12 from follows
13 group by follower_user_id)
14 select uf1.user_id,
15 username,
16 coalesce(followers, 0) as followers,
17 coalesce(following, 0) as following
18 from user_follows uf1
19 left join user_followers uf2 on uf1.user_id = uf2.user_id
20 left join users u on u.id = uf1.user_id
21 order by followers desc;
22)
23
24-- view #2 - most active users - users WITH the most streams in the last 30 days
25CREATE OR REPLACE VIEW user_activity_last_30_days AS
26(
27 WITH streams_per_user AS (SELECT ss.user_id, COUNT(ss.song_id) AS stream_count
28 FROM song_streams ss
29 WHERE ss.streamed_at BETWEEN current_date - 30 and now()
30 GROUP BY ss.user_id)
31 SELECT u.username, spu.*
32 FROM users u
33 JOIN streams_per_user spu ON u.id = spu.user_id
34 ORDER BY stream_count DESC
35);
36
37-- view #3 - average review grade and number of review per song
38CREATE OR REPLACE VIEW song_average_grade AS
39(
40 WITH avg_grade AS (SELECT song_id,
41 AVG(r.grade) AS avg_grade,
42 COUNT(r.grade) AS num_reviews
43 FROM reviews r
44 GROUP BY r.song_id)
45 SELECT s.id AS song_id,
46 s.title AS song_title,
47 u.username AS released_by,
48 u.id AS user_id,
49 ag.avg_grade,
50 ag.num_reviews
51 FROM songs s
52 JOIN avg_grade ag ON ag.song_id = s.id
53 JOIN users u ON u.id = s.owner_artist_id
54 ORDER BY avg_grade DESC, num_reviews DESC
55);
56
57
58-- view #4 - streams per artist in the last 30 days
59
60CREATE OR REPLACE VIEW artist_popularity_last_30_days AS
61WITH streams_count AS (
62 SELECT ss.song_id, COUNT(*) AS cnt
63 FROM song_streams ss
64 WHERE ss.streamed_at >= CURRENT_TIMESTAMP - INTERVAL '30 days'
65 GROUP BY ss.song_id
66),
67artist_listens AS (
68 SELECT
69 a.id AS artist_id,
70 a.display_name AS artist_display_name,
71 COALESCE(SUM(sc.cnt), 0) AS total_listens
72 FROM artists a
73 LEFT JOIN songs s ON s.owner_artist_id = a.id
74 LEFT JOIN streams_count sc ON sc.song_id = s.id
75 GROUP BY a.id, a.display_name
76)
77SELECT
78 ROW_NUMBER() OVER (ORDER BY total_listens DESC) AS rank,
79 artist_id,
80 artist_display_name,
81 total_listens
82FROM artist_listens
83ORDER BY total_listens DESC;
84
85
86-- view #5 - most popular songs in the last 30 days
87
88CREATE OR REPLACE VIEW most_popular_songs_last_30_days AS
89WITH stream_counts AS (
90 SELECT song_id, 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 s.id AS song_id,
97 s.title AS song_title,
98 a.display_name AS artist_display_name,
99 s.visibility AS song_visibility,
100 u.username AS label_admin_username,
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 label_admins la ON s.published_by_label_admin_id = la.id
107LEFT JOIN labels l ON l.id = la.label_id
108LEFT JOIN users u ON u.id = la.user_id
109ORDER BY sc.total_streams DESC;
110
111
112
113-- view #6 - label's artists information
114
115CREATE OR REPLACE VIEW label_artists_info AS
116SELECT
117 l.name AS label_name,
118 a.display_name AS artist_display_name,
119 COUNT(DISTINCT s.id) AS songs,
120 COUNT(DISTINCT f.follower_user_id) AS followers
121FROM labels l
122JOIN artist_labels al ON al.label_id = l.id
123JOIN artists a ON a.id = al.artist_id
124LEFT JOIN songs s ON s.owner_artist_id = a.id
125LEFT JOIN follows f ON f.followed_user_id = a.user_id
126GROUP BY l.name, a.id, a.display_name
127ORDER BY l.name, a.display_name;
128
129