过滤两个表中的数据

时间:2012-01-23 11:10:40

标签: mysql sql left-join

请帮助提出请求。

有两个表,artistalbum。 我想只选择那些专辑中包含图片的艺术家。 也就是说,如果演员有10张专辑,其中只有一张有图片或不包含,我想跳过(只有所有专辑艺术家都有图片)

表艺术家:

artist_id
---------|
1        |
2        |

表相册:

artist_id | album_id | picture_id
---------------------------------
1         | 122...   | true 
1         | 123...   | false
2         | 124...   | true
2         | 125...   | true

所以,我想只选择artist_id=2的艺术家(因为所有专辑都有图片);

3 个答案:

答案 0 :(得分:6)

有很多解决方案,我想到的第一个是一个非常简单的子选择,以排除拥有没有图像的相册的艺术家:

SELECT
  *
FROM
  artist a
WHERE
  artist_id NOT IN 
    (SELECT DISTINCT artist_id FROM album WHERE picture_id = false);

修改
如果您存储的艺术家没有专辑,那么这些也必须被排除在外(请查看评论以获得解释)。在这种情况下,你必须添加如下内容:

AND
  1 <= (SELECT COUNT(*) FROM album WHERE artist_id = a.artist_id)

答案 1 :(得分:4)

您可以使用GROUP BY子句查找艺术家的专辑数量。然后,您可以将此计数与制作的计数进行比较。可以在HAVING子句中使用聚合函数来消除组:

SELECT artist_id
FROM albums
GROUP BY artist_id
HAVING COUNT(1) = COUNT(CASE WHEN picture_id THEN 1 ELSE NULL END)

完整示例:

SELECT artist.artist_id, artist.name
FROM artist
INNER JOIN albums ON artist.artist_id = albums.artist_id
GROUP BY artist.artist_id, artist.name
HAVING COUNT(album_id) = COUNT(CASE WHEN picture_id THEN 1 ELSE NULL END)

答案 2 :(得分:0)

使用MIN()运算符的另一个没有子选择的解决方案 - 如果最小值为TRUE,则所有值都为真:

SELECT artists.artist_id,MIN(picture_id)
FROM artists
INNER JOIN albums ON artists.artist_id = albums.artist_id
GROUP BY artists.artist_id
HAVING MIN(IFNULL(picture_id, 0)) > 0

修改

修改了查询,在MIN()opertor中将空值替换为0,这样更干净。