Files
MusicServer/internal/db/queries/statistics.sql
T
Sansan 080bacae80
CI / integration (push) Successful in 18s
CI / test (push) Successful in 22s
CI / publish (push) Skipped
CI / docker (push) Successful in 41s
Add GET /api/v1/statistics/soundtracks with every soundtrack and its songs
The other soundtrack statistics are capped at 100, so a client that shows every soundtrack (the MusicPlayer statistics tab) had no way to get them all. This one has no limit and is sorted by name.
2026-10-06 23:14:49 +02:00

210 lines
6.4 KiB
SQL

-- Most played soundtracks with their songs
-- name: GetMostPlayedSoundtracksWithSongs :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played,
'file_name', s.file_name
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.times_played DESC, g.soundtrack_name
LIMIT $1;
-- Least played soundtracks with their songs
-- name: GetLeastPlayedSoundtracksWithSongs :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played,
'file_name', s.file_name
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.times_played ASC, g.soundtrack_name
LIMIT $1;
-- Most played songs with their soundtrack info
-- name: GetMostPlayedSongsWithSoundtrack :many
SELECT
s.soundtrack_id as soundtrack_id,
g.uuid as soundtrack_uuid,
s.uuid as song_uuid,
g.soundtrack_name,
s.song_name,
s.path,
s.times_played,
s.file_name
FROM song s
JOIN soundtrack g ON s.soundtrack_id = g.id
WHERE g.deleted IS NULL
ORDER BY s.times_played DESC, s.song_name
LIMIT $1;
-- Least played songs with their soundtrack info
-- name: GetLeastPlayedSongsWithSoundtrack :many
SELECT
s.soundtrack_id as soundtrack_id,
g.uuid as soundtrack_uuid,
s.uuid as song_uuid,
g.soundtrack_name,
s.song_name,
s.path,
s.times_played,
s.file_name
FROM song s
JOIN soundtrack g ON s.soundtrack_id = g.id
WHERE g.deleted IS NULL
ORDER BY s.times_played ASC, s.song_name
LIMIT $1;
-- Soundtracks that have never been played (times_played = 0)
-- name: GetNeverPlayedSoundtracks :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.added,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.times_played = 0
GROUP BY g.id, g.soundtrack_name, g.times_played, g.added
ORDER BY g.soundtrack_name;
-- Last played soundtracks (most recently played)
-- name: GetLastPlayedSoundtracks :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.last_played IS NOT NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.last_played DESC
LIMIT $1;
-- Oldest played soundtracks (least recently played, but has been played at least once)
-- name: GetOldestPlayedSoundtracks :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.last_played IS NOT NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.last_played ASC
LIMIT $1;
-- Get statistics summary
-- name: GetStatisticsSummary :one
SELECT
COUNT(*) as total_soundtracks,
COALESCE(SUM(CASE WHEN times_played > 0 THEN 1 ELSE 0 END), 0)::bigint as played_soundtracks,
COALESCE(SUM(CASE WHEN times_played = 0 THEN 1 ELSE 0 END), 0)::bigint as never_played_soundtracks,
COALESCE(SUM(times_played), 0)::bigint as total_soundtrack_plays,
COALESCE(AVG(times_played), 0)::float as avg_soundtrack_plays,
COALESCE(MAX(times_played), 0)::bigint as max_soundtrack_plays,
COALESCE(MIN(times_played), 0)::bigint as min_soundtrack_plays
FROM soundtrack
WHERE deleted IS NULL;
-- Every soundtrack with its songs, by name
-- name: GetAllSoundtracksWithSongs :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played,
'file_name', s.file_name
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.soundtrack_name;