| 1 | DROP VIEW user_follow_info;
|
|---|
| 2 | DROP VIEW user_activity_last_30_days;
|
|---|
| 3 | DROP VIEW song_average_grade;
|
|---|
| 4 |
|
|---|
| 5 | -- view #1 - for each user get followers and following
|
|---|
| 6 | create 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
|
|---|
| 25 | CREATE 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
|
|---|
| 38 | CREATE 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 |
|
|---|
| 60 | CREATE OR REPLACE VIEW artist_popularity_last_30_days AS
|
|---|
| 61 | WITH 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 | ),
|
|---|
| 67 | artist_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 | )
|
|---|
| 77 | SELECT
|
|---|
| 78 | ROW_NUMBER() OVER (ORDER BY total_listens DESC) AS rank,
|
|---|
| 79 | artist_id,
|
|---|
| 80 | artist_display_name,
|
|---|
| 81 | total_listens
|
|---|
| 82 | FROM artist_listens
|
|---|
| 83 | ORDER BY total_listens DESC;
|
|---|
| 84 |
|
|---|
| 85 |
|
|---|
| 86 | -- view #5 - most popular songs in the last 30 days
|
|---|
| 87 |
|
|---|
| 88 | CREATE OR REPLACE VIEW most_popular_songs_last_30_days AS
|
|---|
| 89 | WITH 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 | )
|
|---|
| 95 | SELECT
|
|---|
| 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
|
|---|
| 103 | FROM stream_counts sc
|
|---|
| 104 | JOIN songs s ON s.id = sc.song_id
|
|---|
| 105 | JOIN artists a ON s.owner_artist_id = a.id
|
|---|
| 106 | LEFT JOIN label_admins la ON s.published_by_label_admin_id = la.id
|
|---|
| 107 | LEFT JOIN labels l ON l.id = la.label_id
|
|---|
| 108 | LEFT JOIN users u ON u.id = la.user_id
|
|---|
| 109 | ORDER BY sc.total_streams DESC;
|
|---|
| 110 |
|
|---|
| 111 |
|
|---|
| 112 |
|
|---|
| 113 | -- view #6 - label's artists information
|
|---|
| 114 |
|
|---|
| 115 | CREATE OR REPLACE VIEW label_artists_info AS
|
|---|
| 116 | SELECT
|
|---|
| 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
|
|---|
| 121 | FROM labels l
|
|---|
| 122 | JOIN artist_labels al ON al.label_id = l.id
|
|---|
| 123 | JOIN artists a ON a.id = al.artist_id
|
|---|
| 124 | LEFT JOIN songs s ON s.owner_artist_id = a.id
|
|---|
| 125 | LEFT JOIN follows f ON f.followed_user_id = a.user_id
|
|---|
| 126 | GROUP BY l.name, a.id, a.display_name
|
|---|
| 127 | ORDER BY l.name, a.display_name;
|
|---|
| 128 |
|
|---|
| 129 |
|
|---|