sql - 当记录不存在时忽略 WHERE 子句
问题描述
我知道有很多标题相似的主题,但它们似乎与其他案例有关。我有 3 张桌子:
song:
id
title
playlist_song:
id
song_id
playlist_id
stats_record:
id
type // enum SONG_LIKED/SONG_DISLIKED/...
user_id
entity_id // id of an entity stats record refers to
我使用playlist_song将歌曲存储在播放列表中,使用stats_record捕获诸如播放/喜欢/不喜欢之类的内容。
我有一个功能,我想向用户展示他们从不喜欢或不喜欢的歌曲。表示 stats_record要么不存在,要么不存在其类型!= SONG_LIKED/SONG_DISLIKED(针对该特定用户!)
但是,当我尝试构建此查询时,它会显示其他用户也从未喜欢过的歌曲(我只关心当前用户)。我的查询如下所示:
select s.title, sr.type
from song s
left join playlist_song ps on ps.song_id = s.id
left join stats_record sr on sr.entity_id = ps.id
where ps.playlist_id = 'a686e0da-750f-11eb-9da1-bf79c63bacf7'
and ((sr.user_id = 'a26e23b4-7483-11eb-986b-5fc23c9ef85c'
and (not sr.type = 'SONG_LIKED'
and not sr.type = 'SONG_DISLIKED')) or sr.id is null);
我想要实现的是“如果 stats_record 存在,检查它是否不是 SONG_LIKED/DISLIKED,否则忽略”
解决方案
我没有对此进行测试,但我认为反加入会起作用:
select s.title, sr.type
from song s
left join playlist_song ps on ps.song_id = s.id
where
ps.playlist_id = 'a686e0da-750f-11eb-9da1-bf79c63bacf7' and
not exists (
select null
from stats_record sr
where
sr.entity_id = ps.id and
sr.user_id = 'a26e23b4-7483-11eb-986b-5fc23c9ef85c' and
sr.type in ('SONG_LIKED', 'SONG_DISLIKED') -- this might be unnecessary
)
这个结构也非常有效,并且可以容忍重复,尽管我认为在这个例子中你不会有任何重复。
假设这可行,请尝试省略最后一个 where 子句 ( sr.type in...
)。我不认为你会需要它。
推荐阅读
- java - 如何禁用 jsoup@1.10.2+ 的字符转义
- python - 对包含多行字符串的列表执行正则表达式
- google-cloud-platform - 在不同区域的存储桶之间移动谷歌云数据而不产生出口成本?
- python - LookupError:应用程序“应用程序”没有“自定义用户”模型
- angular - 如何在 Ubuntu 的 localhost 中使用 Angular CLI 和自签名 SSL 证书通过 HTTPS 提供服务?
- css - 如何将箭头与相应的圆圈对齐?
- firebase - 除英语以外的其他语言的文本识别失败[firebase ml vision]
- .htaccess - 阿拉伯语作为获取参数在路线中不起作用
- laravel - 获取已删除的产品
- here-api - Here Maps:如何从 Here 车队遥测 api 获取 routeId?