DatabaseCreation: views.sql

File views.sql, 6.0 KB (added by 231058, 5 days ago)
Line 
1-- 1. friend_list
2CREATE OR REPLACE VIEW public.friend_list
3AS SELECT f.id AS friendship_id,
4 u1.id AS user_id,
5 u1.username,
6 u2.id AS friend_id,
7 u2.username AS friend_username,
8 fs.name AS status
9 FROM friendships f
10 JOIN users u1 ON u1.id = f.user_id_high
11 JOIN users u2 ON u2.id = f.user_id_low
12 JOIN friendship_statuses fs ON fs.id = f.status_id
13 WHERE fs.name = 'accepted'
14UNION ALL
15 SELECT f.id AS friendship_id,
16 u2.id AS user_id,
17 u2.username,
18 u1.id AS friend_id,
19 u1.username AS friend_username,
20 fs.name AS status
21 FROM friendships f
22 JOIN users u1 ON u1.id = f.user_id_high
23 JOIN users u2 ON u2.id = f.user_id_low
24 JOIN friendship_statuses fs ON fs.id = f.status_id
25 WHERE fs.name = 'accepted';
26
27-- 2. game_catalog
28CREATE OR REPLACE VIEW public.game_catalog
29AS SELECT g.id AS game_id,
30 g.title,
31 g.release_date,
32 string_agg(DISTINCT ge.name::text, ', '::text) AS genres,
33 string_agg(DISTINCT d.name::text, ', '::text) AS developers,
34 avg(r.rating) AS avg_rating,
35 count(DISTINCT r.id) AS review_count
36 FROM games g
37 LEFT JOIN game_genres gg ON gg.game_id = g.id
38 LEFT JOIN genres ge ON ge.id = gg.genre_id
39 LEFT JOIN game_developers gd ON gd.game_id = g.id
40 LEFT JOIN developers d ON d.id = gd.developer_id
41 LEFT JOIN reviews r ON r.game_id = g.id
42 GROUP BY g.id, g.title, g.release_date;
43
44-- 3. leaderboard
45CREATE OR REPLACE VIEW public.leaderboard
46AS SELECT u.id AS user_id,
47 u.username,
48 p.rank_points,
49 l.country,
50 p.avatar_url,
51 count(DISTINCT mp.id) AS matches_played,
52 count(DISTINCT mp.id) FILTER (WHERE pr.name = 'win') AS wins,
53 CASE
54 WHEN count(DISTINCT mp.id) = 0 THEN 0::numeric
55 ELSE round(count(DISTINCT mp.id) FILTER (WHERE pr.name = 'win')::numeric * 100.0 / count(DISTINCT mp.id)::numeric, 2)
56 END AS win_rate
57 FROM users u
58 JOIN profiles p ON p.user_id = u.id
59 JOIN locations l ON l.id = u.location_id
60 LEFT JOIN match_participants mp ON mp.user_id = u.id
61 LEFT JOIN participant_results pr ON pr.id = mp.result_id
62 GROUP BY u.id, u.username, p.rank_points, l.country, p.avatar_url
63 ORDER BY p.rank_points DESC;
64
65-- 4. match_history
66CREATE OR REPLACE VIEW public.match_history
67AS SELECT m.id AS match_id,
68 g.title AS game,
69 gm.mode_name AS game_mode,
70 t.name AS tournament_name,
71 m.started_at,
72 m.ended_at,
73 EXTRACT(epoch FROM m.ended_at - m.started_at) / 60::numeric AS duration_minutes,
74 l.latitude AS server_lat,
75 l.longitude AS server_lon
76 FROM matches m
77 JOIN games g ON g.id = m.game_id
78 JOIN game_modes gm ON gm.id = m.game_mode_id
79 LEFT JOIN tournaments t ON t.id = m.tournament_id
80 JOIN servers s ON s.id = m.server_id
81 JOIN locations l ON l.id = s.location_id
82 WHERE m.ended_at IS NOT NULL;
83
84-- 5. player_match_stats
85CREATE OR REPLACE VIEW public.player_match_stats
86AS SELECT mp.id AS user_match_id,
87 u.id AS user_id,
88 u.username,
89 m.id AS match_id,
90 g.title AS game,
91 pr.name AS result,
92 mp.score,
93 mp.elo_change,
94 mp.joined_at,
95 jsonb_object_agg(st.name, ps.value) FILTER (WHERE st.id IS NOT NULL) AS stats
96 FROM match_participants mp
97 JOIN users u ON u.id = mp.user_id
98 JOIN matches m ON m.id = mp.match_id AND m.started_at = mp.match_started_at
99 JOIN games g ON g.id = m.game_id
100 LEFT JOIN participant_results pr ON pr.id = mp.result_id
101 LEFT JOIN participant_stats ps ON ps.match_participant_id = mp.id
102 LEFT JOIN stat_types st ON st.id = ps.stat_type_id
103 GROUP BY mp.id, u.id, u.username, m.id, g.title, pr.name, mp.score, mp.elo_change, mp.joined_at;
104
105-- 6. tournament_standings
106CREATE OR REPLACE VIEW public.tournament_standings
107AS SELECT t.id AS tournament_id,
108 t.name AS tournament_name,
109 g.title AS game,
110 t.starts_at,
111 t.prize_pool,
112 tm.id AS team_id,
113 tm.name AS team_name,
114 count(DISTINCT m.id) AS matches_played,
115 count(DISTINCT m.id) FILTER (WHERE m.id IS NOT NULL) AS matches_entered
116 FROM tournaments t
117 JOIN games g ON g.id = t.game_id
118 JOIN tournament_teams tt ON tt.tournament_id = t.id
119 JOIN teams tm ON tm.id = tt.team_id
120 LEFT JOIN matches m ON m.tournament_id = t.id
121 GROUP BY t.id, t.name, g.title, t.starts_at, t.prize_pool, tm.id, tm.name
122 ORDER BY t.id, (count(DISTINCT m.id)) DESC;
123
124-- 7. unread_notifications
125CREATE OR REPLACE VIEW public.unread_notifications
126AS SELECT n.id AS notification_id,
127 u.id AS user_id,
128 u.username,
129 nt.name AS type,
130 n.message,
131 n.is_read,
132 g.title AS preferred_game
133 FROM notifications n
134 JOIN users u ON u.id = n.user_id
135 JOIN notification_types nt ON nt.id = n.type_id
136 LEFT JOIN preferences pr ON pr.user_id = n.preference_user_id AND pr.game_id = n.preference_game_id
137 LEFT JOIN games g ON g.id = pr.game_id
138 WHERE n.is_read = false
139 ORDER BY n.id DESC;
140
141-- 8. user_all_achievements
142CREATE OR REPLACE VIEW public.user_all_achievements
143AS SELECT u.id AS user_id,
144 u.username,
145 a.id AS achievement_id,
146 a.title AS achievement_title,
147 a.description AS achievement_description,
148 g.title AS game,
149 ua.unlocked_at
150 FROM user_achievements ua
151 JOIN users u ON u.id = ua.user_id
152 JOIN achievements a ON a.id = ua.achievement_id
153 JOIN games g ON g.id = a.game_id
154 ORDER BY ua.unlocked_at DESC;
155
156-- 9. user_profile
157CREATE OR REPLACE VIEW public.user_profile
158AS SELECT u.id AS user_id,
159 u.username,
160 u.email,
161 l.latitude,
162 l.longitude,
163 u.created_at,
164 p.avatar_url,
165 p.bio,
166 l.country,
167 p.rank_points,
168 sp.name AS subscription_type,
169 s.start_at AS subscription_start,
170 s.end_at AS subscription_end
171 FROM users u
172 JOIN profiles p ON p.user_id = u.id
173 JOIN locations l ON l.id = u.location_id
174 LEFT JOIN subscriptions s ON s.user_id = u.id AND (s.end_at IS NULL OR s.end_at >= CURRENT_DATE) AND s.start_at <= CURRENT_DATE
175 LEFT JOIN subscription_plans sp ON sp.id = s.plan_id;