【问题标题】:Subquery returns multiple rows in HAVING clause子查询在 HAVING 子句中返回多行
【发布时间】:2018-11-15 07:49:18
【问题描述】:

我想拿到2016年7月大部分借3类片子的客户

SELECT c_firstName, c_lastName, rental.c_ID
FROM customer, rental
GROUP BY rental.c_ID HAVING rental.c_ID=MAX((SELECT COUNT(rental.c_ID) 
FROM customer, copies, rentalprocess, rental, film
WHERE customer.c_ID=rental.c_ID AND rentalprocess.r_ID=rental.r_ID AND
      rentalprocess.s_ID=copies.s_ID AND film.f_ID=copies.f_ID AND
      f_category=3 AND r_date LIKE "2016-07%" GROUP BY rental.c_ID))

但是 ir 不起作用,因为它说子查询返回不止一行

我能做什么?

【问题讨论】:

  • 这是什么rmdbs?甲骨文、MySQL 等?
  • 从不FROM 子句中使用逗号。 始终使用正确、明确、标准 JOIN 语法。
  • 是 MySQL RMDBS
  • RDBMS,关系数据库管理系统:)
  • 使用正确的JOIN。它已经存在了 20 多年。

标签: mysql sql subquery having


【解决方案1】:

Max()是聚合函数,需要在select语句中

SELECT 
  c_firstName
  , c_lastName
  , rental.c_ID
FROM customer, rental
GROUP BY rental.c_ID 
HAVING rental.c_ID=
  (
  select 
    MAX(i.iID) 
  from 
    (
    SELECT 
      COUNT(rental.c_ID) iID
    FROM customer, copies, rentalprocess, rental, film
    WHERE 
      customer.c_ID=rental.c_ID AND 
      rentalprocess.r_ID=rental.r_ID AND
      rentalprocess.s_ID=copies.s_ID AND 
      film.f_ID=copies.f_ID AND
      f_category=3 
      AND r_date LIKE "2016-07%" 
    GROUP BY rental.c_ID
    ) i
  )

在这种情况下,子选择返回多行,但随后您获取该查询的最大值

Linoff 先生的评论是正确的,您应该使用显式连接:

SELECT 
  c_firstName
  , c_lastName
  , rental.c_ID
FROM customer, rental
GROUP BY rental.c_ID 
HAVING rental.c_ID=
  (
  select 
    MAX(i.iID) 
  from 
    (
    SELECT 
      COUNT(rental.c_ID) iID
    FROM 
      customer 
      inner join rental 
        on customer.c_ID=rental.c_ID
      inner join rentalprocess 
        on rentalprocess.r_ID=rental.r_ID
      inner join copies 
        on rentalprocess.s_ID=copies.s_ID
      inner join film on film.f_ID=copies.f_ID
    WHERE 
      f_category=3 
      AND r_date LIKE "2016-07%" 
    GROUP BY rental.c_ID
    ) i
  )

【讨论】:

  • 现在它说每个派生表都必须有自己的别名
  • 所以给每个子查询一个别名..(如果那个 SQL 的缩进不是到处都是,这会容易得多)
  • @CaiusJard 手机投稿 :(
  • @EoinS 是的,对不起,我应该明确表示我的评论是针对 Grevak 的——在事情的规模上,“子查询需要别名”是我期望的错误/小错别字之一OP 自己解决,因为它基本上涉及找到一个括号并在其后放一个字母 A。我一直担心在这里提出问题会成为一种精神上的辞职,人们不再准备尝试调试任何东西与问题相关,并期望提供完美的解决方案:/坚持使用移动 SO 的荣誉;我也这样做,这很痛苦:)
【解决方案2】:

您的代码应如下所示,在代码中正确连接表格。 我不知道哪些列和表最适合该解决方案,因为我没有您的完整架构。但这应该会提供更快的查询。如果您愿意,可以在选择中添加更多列。

select c_firstName | ' ' | c_lastName, count(rental.c_ID) as rentalCustomer
    from customer
     inner join rental
       on join " connect the both tables"
      innner join rentalprocess
       on "connect rental with rentalprocess"
      inner join copies
         on " connect rentalprocess with copies"
       inner join film
        on "connect copies with film"
    WHERE customer.c_ID=rental.c_ID AND 
    rentalprocess.r_ID=rental.r_ID AND
      rentalprocess.s_ID=copies.s_ID AND 
    film.f_ID=copies.f_ID AND
      f_category=3 AND r_date LIKE "2016-07%"
     group by c_firstName, c_lastName, rental.c_ID
    order by rental.c_ID desc;

【讨论】:

  • 如果你要达到这个程度,你可以一路走下去,把加入 ON 条件从 WHERE 子句中拉出来——这就是它们在 1980 年代最初发布的版本中的位置!:)跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 2016-08-24
  • 2013-09-22
  • 2016-10-25
相关资源
最近更新 更多