feat(db): add LoadRadioCandidates query
Single SELECT that joins tracks with general_likes (for is_liked) and an aggregated LATERAL subquery on play_events (for last_played_at, play_count, skip_count). Excludes seed + tracks played in the last N hours. Drives the M3 weighted shuffle scoring.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
-- name: LoadRadioCandidates :many
|
||||
-- Returns all tracks except the seed and any played by the user within
|
||||
-- the last $3 hours, joined with the stats needed for scoring:
|
||||
-- is_liked — boolean from general_likes for this user
|
||||
-- last_played_at — max(play_events.started_at) for this user/track
|
||||
-- play_count — count of play_events for this user/track
|
||||
-- skip_count — play_events where was_skipped=true
|
||||
SELECT
|
||||
sqlc.embed(t),
|
||||
(l.user_id IS NOT NULL)::bool AS is_liked,
|
||||
pe.last_played_at::timestamptz AS last_played_at,
|
||||
pe.play_count,
|
||||
pe.skip_count
|
||||
FROM tracks t
|
||||
LEFT JOIN general_likes l ON l.user_id = $1 AND l.track_id = t.id
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
max(started_at) AS last_played_at,
|
||||
count(*) AS play_count,
|
||||
count(*) FILTER (WHERE was_skipped) AS skip_count
|
||||
FROM play_events
|
||||
WHERE user_id = $1 AND track_id = t.id
|
||||
) pe ON true
|
||||
WHERE t.id <> $2
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM play_events
|
||||
WHERE user_id = $1 AND track_id = t.id
|
||||
AND started_at > now() - $3 * interval '1 hour'
|
||||
);
|
||||
Reference in New Issue
Block a user