I want to write a query that would fetch a page of artists with top 3 most listened tracks. Is it possible to accomplish this with a single repository query? Or would it be better to create a query fetching most popular artists first and then fetch top 3 tracks for each artist using separate queries?
Initially I wanted to accomplish it with a non-native query like this (which only fetches top popular artists by tracks and doesn't limit tracks):
@Query(value = "SELECT author FROM Artist artist JOIN artist.tracks track JOIN track.usersListenedTrack ult" +
" WHERE ult.listenedAt >= :time" +
" GROUP BY artist" +
" ORDER BY COUNT(artist) DESC")
Page<Artist> findPopularArtistsByPeriod(Instant time, Pageable pageable);
But because non-native queries don't support LIMIT
operator I guess I need to use a native sql (postgres in my case)
So, the query should look something like this:
@Query(native = true, value = "SELECT * FROM artist a " +
" INNER JOIN artist_tracks at ON at.artist_id = a.id" +
" INNER JOIN tracks t ON at.track_id = t.id" +
" INNER JOIN (SELECT * from listened_tracks lt WHERE ?????) tmp ON tmp.track_id = t.id" +
" WHERE lt.listened_at >= :time" +
" GROUP BY artist" +
" ORDER BY COUNT(artist) DESC")
Page<Artist> findPopularArtistsByPeriod(Instant time, Pageable pageable);
But I'm not sure how to select top 3 tracks from listened_tracks
grouped by artist
So, my questions are:
- Is it ok to fetch such data in one query?
- What is the right way of querieng the
listened_tracks
table to fetch top 3 tracks by artist