Поиск всех плейлистов с треком с определенным именем исполнителя? - PullRequest
1 голос
/ 04 июля 2019

У меня есть две таблицы Postgres: playlists и tracks.

Я создал playlists_tracks, который является отношением many_to_many между списками воспроизведения и дорожками.

Дорожки содержат несколько столбцов, но я смотрю на это artist.

Какой самый быстрый способ запросить список всех плейлистов, которые содержат хотя бы одну дорожку с именем исполнителя, содержащим, скажем, "The Beatles"?Я с трудом нахожу в голове эффективный способ сделать это.

Ответы [ 2 ]

0 голосов
/ 04 июля 2019

Самая дешевая и простая операция DISTINCT состоит в том, чтобы .. не умножать строки в первую очередь.
EXISTS полусоединение делает это для вашего запроса:

SELECT *
FROM   playlists p
WHERE  EXISTS (
   SELECT -- can be empty for EXISTS
   FROM   playlists_tracks pt
   JOIN   tracks t USING (track_id)
   WHERE  pt.playlist_id = p.playlist_id
   AND    t.artist = 'The Beatles'
   );

Предполагая типичную реализацию "многие ко многим", как подробно описано здесь:

(Вы можете даже вкладывать EXISTS вместо объединения в подзапросе. Не уверен, поможет ли это больше.)

Если таблицы большие, indexes может помочь производительности.Идеально подходит для конкретного запроса:

  • CREATE INDEX ON tracks (artist, track_id) - столбцы в этом порядке
  • CREATE INDEX ON playlists_tracks (track_id, playlist_id) - столбцы в этом порядке

Похожие:

0 голосов
/ 04 июля 2019

Вы должны присоединиться к 3 столам и группировать по плейлисту следующим образом:

select p.playlistid, p.name
from playlists p 
inner join playlists_tracks pt on pt.playlistid = p.playlistid
inner join (select * from tracks where artist = 'The Beatles') t on t.trackid = pt.trackid
group by p.playlistid, p.name

или используя distinct:

select distinct p.*
from playlists p 
inner join playlists_tracks pt on pt.playlistid = p.playlistid
inner join tracks t on t.trackid = pt.trackid
where t.artist = 'The Beatles'
...