涉及子查询的查询
Posted
技术标签:
【中文标题】涉及子查询的查询【英文标题】:Queries involving a subquery 【发布时间】:2014-06-14 03:49:55 【问题描述】:我有一个存储有关艺术家、乐队和专辑信息的数据库,我正在尝试为拥有超过 1 张专辑的乐队选择乐队名称和专辑标题。
band_id, name, year_formed
1, blink182, 1990
2, fall out boy, 1997
3, u2, 1982
4, coldplay, 1990
5, zach brown band, 2002
和专辑
album_id, title, band_id
1, take off your pants and jack it, 1
2, stars, 3
3, fbgm, 3
4, reach, 3
5, yup, 4
这似乎不是一个太难的问题,但我无法终生解决。 问题似乎在于从 select 语句中获取专辑标题和乐队名称。
SELECT b.name, alb.title
FROM band as b, album as alb
WHERE exists (SELECT * FROM album as al WHERE b.bid = alb.bid)
返回所有乐队名称及其专辑名称。我的猜测是让子查询处理找到不止一张专辑的乐队,但我完全不知道如何做到这一点。一般而言,子查询一直让我陷入循环,因此任何关于它们在概念上如何工作的精彩描述都将不胜感激。
【问题讨论】:
【参考方案1】:我认为您希望使用JOIN
,而不是使用EXISTS
:
SELECT b.name, a.title
FROM band b
JOIN album a ON b.bid = a.bid
A Visual Explanation of SQL Joins
如果您要查找具有多个标题的乐队,那么您还需要使用聚合查询:
SELECT b.name, a.title
FROM band b
JOIN album a ON b.band_id = a.band_id
JOIN (SELECT band_id
FROM album
GROUP BY band_id
HAVING COUNT(*) > 1) c ON b.band_id = c.band_id
【讨论】:
【参考方案2】:你可以试试这个查询。您需要使用group_concat()
和JOIN
来获取所有标题。在这里查看演示小提琴http://sqlfiddle.com/#!2/3d689/3。
select b.name,tab.new_title
from band b
inner join
(
select `band_id`,
group_concat(`title`) as new_title
from album
group by `band_id`
having count(*) > 1
) tab on b.`band_id` = tab.`band_id`
【讨论】:
【参考方案3】:你可以使用LEFT JOIN
:
SELECT b.name,x.title AS Title
FROM band b LEFT JOIN ( SELECT band_id
, GROUP_CONCAT(title SEPARATOR ', ') AS Title
FROM album
GROUP BY band_id
HAVING COUNT(*) > 1) x ON b.band_id = x.band_id
WHERE x.band_id IS NOT NULL
SQLFiddle
【讨论】:
这似乎有效。谢谢!为什么我应该专门使用左连接? @user95420 :album
表中可能存在band
表中不存在的记录,反之亦然,因此INNER JOIN
不考虑此记录。逻辑上还可以,但考虑到数据完整性,最好使用LEFT JOIN
。以上是关于涉及子查询的查询的主要内容,如果未能解决你的问题,请参考以下文章