我有两个Postgres表:playlists
和tracks
。
我创建了playlists_tracks
,它是播放列表和曲目之间的many_to_many关系。
轨道包含多列,但我要查看的是artist
。
以最快的方式查询所有包含至少一个曲目且其歌手姓名包含“甲壳虫乐队”的曲目的列表的情况?我很难用一种有效的方法来解决问题。
答案 0 :(得分:0)
您必须像这样加入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'
答案 1 :(得分:0)
最便宜和最简单的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
而不是子查询中的联接。不确定是否有帮助。)
如果表很大,索引可以帮助提高性能。特定查询的理想选择:
CREATE INDEX ON tracks (artist, track_id)
-以此顺序排列的列CREATE INDEX ON playlists_tracks (track_id, playlist_id)
-以此顺序排列的列相关: