SQL : 如何声明一个集合中的元素不能出现在另一个集合中?
SQL : How to state that no element of a set can be present in another set?
假设我有这个数据库方案:
这个问题我纠结了一个多小时:
"Select all albums of which no track has been used in a playlist".
我想做这样的事情:
SELECT parentalbum.albumid FROM album AS parentalbum
INNER JOIN track
ON track.albumid = parentalbum.albumid
INNER JOIN playlistitem
ON track.trackid = playlistitem.trackid // Join the 3 tables
WHERE NOT ((SELECT track.trackid FROM album
INNER JOIN track
ON album.albumid = track.albumid
WHERE track.albumid = parentalbum.albumid ) // Select songs from one album
IN playlistitem.trackid ) // Check if at least one element of the album is in a playlist? (faulty)
我的查询可能完全错误,所以我将不胜感激。
编辑:我忘了说,我被要求使用相关子查询来解决这个问题。谢谢!
使用 left join
松散地连接 table。然后按专辑分组,只取 playlistitem
table
中的零曲目
select a.id, a.title
from album a
left join track t on t.albumid = a.albumid
left join playlistitem pi on pi.trackid = t.trackid
group by a.id, a.title
having sum(case when pi.trackid is not null then 1 else 0 end) = 0
首先创建一个子查询,它有一个内部联接,用于将曲目和播放列表项中连接的所有结果联接在一起。然后检查 albumid 是否不在该列表中。我使用 distinct 只获取子查询中 albumid 的唯一值。
SELECT a.albumid
FROM album a
WHERE a.albumid NOT IN
( SELECT DISTINCT t.albumid
FROM track t
INNER JOIN playlistitem p
ON p.trackid = t.trackid
)
NOT EXISTS()
是答案:
SELECT * -- Select all albums
FROM album a
WHERE NOT EXISTS ( -- of which no track
SELECT * FROM track t
WHERE t.albumid = a.albumid
AND EXISTS (
SELECT * FROM playlistitem pi -- has been used in a playlist
WHERE pi.trackid = t.trackid
)
)
;
更简单:
SELECT * -- Select all albums
FROM album a
WHERE NOT EXISTS ( -- of which no track
SELECT *
FROM track t -- has been used in a playlist
JOIN playlistitem pi ON t.trackid = pi.trackid
WHERE t.albumid = a.albumid
)
;
使用相关子查询但不使用 NOT EXISTS
的替代版本,只是因为...
Select a.*
From Album As a
Where 0 = (
Select Count(*)
From PlaylistItem As pi
Join Track As t on pi.TrackID = t.TrackID
Where t.AlbumID = a.AlbumID);
假设我有这个数据库方案:
这个问题我纠结了一个多小时: "Select all albums of which no track has been used in a playlist".
我想做这样的事情:
SELECT parentalbum.albumid FROM album AS parentalbum
INNER JOIN track
ON track.albumid = parentalbum.albumid
INNER JOIN playlistitem
ON track.trackid = playlistitem.trackid // Join the 3 tables
WHERE NOT ((SELECT track.trackid FROM album
INNER JOIN track
ON album.albumid = track.albumid
WHERE track.albumid = parentalbum.albumid ) // Select songs from one album
IN playlistitem.trackid ) // Check if at least one element of the album is in a playlist? (faulty)
我的查询可能完全错误,所以我将不胜感激。
编辑:我忘了说,我被要求使用相关子查询来解决这个问题。谢谢!
使用 left join
松散地连接 table。然后按专辑分组,只取 playlistitem
table
select a.id, a.title
from album a
left join track t on t.albumid = a.albumid
left join playlistitem pi on pi.trackid = t.trackid
group by a.id, a.title
having sum(case when pi.trackid is not null then 1 else 0 end) = 0
首先创建一个子查询,它有一个内部联接,用于将曲目和播放列表项中连接的所有结果联接在一起。然后检查 albumid 是否不在该列表中。我使用 distinct 只获取子查询中 albumid 的唯一值。
SELECT a.albumid
FROM album a
WHERE a.albumid NOT IN
( SELECT DISTINCT t.albumid
FROM track t
INNER JOIN playlistitem p
ON p.trackid = t.trackid
)
NOT EXISTS()
是答案:
SELECT * -- Select all albums
FROM album a
WHERE NOT EXISTS ( -- of which no track
SELECT * FROM track t
WHERE t.albumid = a.albumid
AND EXISTS (
SELECT * FROM playlistitem pi -- has been used in a playlist
WHERE pi.trackid = t.trackid
)
)
;
更简单:
SELECT * -- Select all albums
FROM album a
WHERE NOT EXISTS ( -- of which no track
SELECT *
FROM track t -- has been used in a playlist
JOIN playlistitem pi ON t.trackid = pi.trackid
WHERE t.albumid = a.albumid
)
;
使用相关子查询但不使用 NOT EXISTS
的替代版本,只是因为...
Select a.*
From Album As a
Where 0 = (
Select Count(*)
From PlaylistItem As pi
Join Track As t on pi.TrackID = t.TrackID
Where t.AlbumID = a.AlbumID);