python - 如何在多对多关系中获得总数?
问题描述
我正在使用 wxpython 和 sqlite3 构建一个简单的歌曲管理器。
有以下几张表
- 歌曲
- 文件
- 标签
- 播放列表
歌曲和文件具有一对一的关系。
歌曲和标签具有多对多关系。
歌曲和播放列表具有多对多关系。
您可以在下面看到我正在使用的表查询:
create_songs_table_query = """ CREATE TABLE IF NOT EXISTS songs (
song_id integer PRIMARY KEY AUTOINCREMENT,
title text NOT NULL,
artist text NOT NULL,
added_timestamp integer NOT NULL,
file_id INTEGER NULL,
FOREIGN KEY (file_id)
REFERENCES files (file_id)
ON DELETE CASCADE
); """
create_files_table_query = """ CREATE TABLE IF NOT EXISTS files (
file_id integer PRIMARY KEY AUTOINCREMENT,
filename text NULL,
size integer NULL,
song_id INTEGER NOT NULL,
FOREIGN KEY (song_id)
REFERENCES songs (song_id)
ON DELETE CASCADE
); """
create_tags_table_query = """CREATE TABLE IF NOT EXISTS tags (
tag_id integer PRIMARY KEY AUTOINCREMENT,
tag_text text NOT NULL,
tag_timestamp integer NULL,
); """
create_songs_tags_table_query = """CREATE TABLE IF NOT EXISTS songs_tags (
song_tag_id integer PRIMARY KEY AUTOINCREMENT,
song_id INTEGER NOT NULL,
FOREIGN KEY (song_id)
REFERENCES songs (song_id)
ON DELETE CASCADE,
tag_id INTEGER NOT NULL,
FOREIGN KEY (tag_id)
REFERENCES tags (tag_id)
ON DELETE CASCADE
); """
create_playlists_table_query = """CREATE TABLE IF NOT EXISTS playlists (
playlist_id integer PRIMARY KEY AUTOINCREMENT,
playlist_title text NOT NULL,
created_timestamp INTEGER NOT NULL,
updated_timestamp INTEGER NULL,
); """
create_songs_playlists__table_query = """CREATE TABLE IF NOT EXISTS songs_playlists (
song_playlist_id integer PRIMARY KEY AUTOINCREMENT,
song_id INTEGER NOT NULL,
FOREIGN KEY (song_id)
REFERENCES songs (song_id)
ON DELETE CASCADE,
playlist_id INTEGER NOT NULL,
FOREIGN KEY (playlist_id)
REFERENCES playlists (playlist_id)
ON DELETE CASCADE
); """
我正在尝试获取每个播放列表总共有多少首歌曲,包括是否有任何播放列表有 0 首歌曲。
我使用以下查询似乎返回了所需的结果:
SELECT playlists.playlist_id, playlists.playlist_title, COUNT(songs.song_id) as total
FROM playlists
LEFT OUTER JOIN songs_playlists
ON playlists.playlist_id = songs_playlists.playlist_id
LEFT OUTER JOIN songs
ON songs_playlists.song_id = songs.song_id
GROUP BY (songs.song_id)
ORDER BY total DESC
虽然,我不确定它是否完全正确,或者可能有更简单或更有效的方法来做到这一点。
解决方案
我正在尝试获取每个播放列表总共有多少首歌曲,包括是否有任何播放列表有 0 首歌曲。
您确实可以从playlists
table 开始,然后带songs_playlists
a left join
,然后聚合。但是,您不需要songs
表格来获得您想要的结果,更重要的是,您需要group by
播放列表,而不是按歌曲:
select p.playlist_id, p.playlist_title, count(sp.playlist_id) no_songs
from playlists p
left join songs_playlists sp on sp.playlist_id = p.playlist_id
group by p.playlist_id, p.playlist_title
相关子查询也可能是一种可接受的方法,因为它避免了外部聚合的需要:
select
p.*,
(select count(*) from songs_playlists sp where sp.playlist_id = p.playlist_id) no_songs
from playlists p
推荐阅读
- php - 增加数量后如何拆分购物车商品的 ID 号
- php - 我可以在 NodeJS 中生成密钥对,使用公钥在 PHP 中加密数据,然后在 NodeJS 中解密吗?
- php - 在视图文件 codeigniter 中显示数据时出现问题
- excel - VBA:在类模块中模拟 AddressOf 运算符的解决方法
- python - MacOS:在 High Sierra 上 brew install graph-tool
- redhat - 如何确定哪个版本的 yum 库与已安装的特定版本的依赖项兼容?
- prolog - Prolog - 检测有向图中连接节点的谓词
- c# - 使方法易于由第三方调用和配置的最佳方法
- asp.net-core - 在 VS 2019 预览版中没有可用于使用 .Net Core 3.0 的选项
- git - 收到 git push 错误:“您无法推送以下提交,因为它们是由作者姓名不知道 Stash 的用户创作的”