【发布时间】:2019-11-24 14:16:39
【问题描述】:
一直在尝试通过我为自己开发的一些练习题重新介绍自己使用 SQL,但努力寻找解决以下问题的更好方法:
playlists
id title
1 Title1
2 Title2
playlist_clips
id playlist_id clip_id
1 Title1 3
2 Title2 1
playlist_tags
playlist_id tag_id
1 1
1 2
2 2
Clips 和Tags 是两个完全独立的表,我使用playlist_tags 和playlist_clips 将它们连接到playlists 表,以表示双向一对多关系.
我想选择所有具有给定标题的播放列表,并在查询中提供所有标签(在本例中为 [1, 2]),而不仅仅是“至少其中一个”;另外,我想从 playlist_clips 表中查询信息,包括剪辑数量、总播放列表时长等。
这是我想出的:
select p_clips.* from
(
p.id, p.title, CAST(COALESCE(sum(pc.duration_seconds), 0) as UNSIGNED) as total_duration_in_seconds, count(pc.id) as number_of_clips
from playlists p
left join playlist_clips pc on p.id = pc.playlist_id
where p.title like "Test1"
group by id
) as p_clips
inner join
(
select *
from playlists p
left join playlist_tags pt on p.id = pt.playlist_id
where pt.tag_id in (1, 2)
group by id
having count(*) = 2
) as p_tags
on p_clips.id = p_tags.id
虽然从我的测试中我发现它可以工作,但它看起来并不是特别优雅,而且我还认为它在性能方面并不是非常有效。 (我已经从这个示例的代码中删除了不相关的参数,例如select 参数。)
什么是更清洁的方法,或者至少是更优化的方法?
Expected Result:
id title
260 Title1
编辑:对于我最初令人困惑的帖子,我深表歉意,我已尝试清理我的表格及其包含的信息。
【问题讨论】:
-
我想强调的是,这与stackoverflow.com/questions/59018101/… 不同,因为这个版本明确地引入了剪辑表。
-
。 .您的示例数据可能是一个糟糕的选择,因为每个播放列表 ID 只有一个剪辑。我怀疑你真的想要更多。预期结果应包括剪辑。
标签: mysql sql database mariadb