涉及子查询的查询

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

以上是关于涉及子查询的查询的主要内容,如果未能解决你的问题,请参考以下文章

重写 NOT IN,但子查询涉及逗号分隔的字符串 (ID)

基于 Databricks Spark SQL 子查询的查询抛出 TreeNodeException

推荐学Java——数据表高级操作

推荐学Java——数据表高级操作

sqlserver查询树形结构的所有子节点

选择中的左连接与子查询的奇怪问题