【问题标题】:Inexplicable inner query莫名其妙的内部查询
【发布时间】:2009-01-20 20:27:03
【问题描述】:

我有一个嵌套 SQL 查询显示我无法理解的结果。该查询通过 PARTNER_USER 表连接 PARTNER 和 USER 表。合作伙伴基本上是用户的集合,此查询的目的是找出第 20 个用户何时向 ID 为 34 的合作伙伴注册:

select p.partner_id id,
       u.created_on launch_date
from   user u join partner_user pu
using (user_id) join partner p
using (partner_id)
where  p.partner_id = 34
and    u.user_id     =
       (select  nu.user_id
       from     user nu
       join     partner_user npu using (user_id)
       join     partner np using (partner_id)
       where    np.partner_id = 34
       order by nu.created_on limit 19, 1)

但是,如果我将倒数第二行更改为

       where    np.partner_id = p.partner_id

查询失败并显示错误消息“子查询返回超过 1 行”。 为什么第一个查询有效,而第二个查询无效?他们看起来和我一样。

谢谢, 唐

【问题讨论】:

  • 您有 19 个限制,但您希望 1 个?
  • 不,我的限制是从 19 日到 19 日 + 1 = 20 日。也就是说,我只想要第 20 个结果
  • 只是想您可能想知道,关于您在下面的评论,只要外部查询不是连接(如我的其他答案所示),查询似乎就可以正常工作。但是,如果外部查询是连接(如在这个问题中),则会出现“多行”错误。我不知道为什么。 :)

标签: mysql sql mysql-error-1242


【解决方案1】:

JPunyon 是对的。必须先运行一个或另一个查询,然后再对其结果进行修剪。

如果您查看编写的查询,则外部查询必须知道内部查询的结果才能应用其 where 子句。但是,当您指定

where    np.partner_id = p.partner_id

在内部查询中,然后您尝试使内部查询知道外部查询的结果以应用其 where 子句。这是一个循环依赖。

作为人类,您可以阅读查询,并且可以看出在这种特殊情况下,您在外部查询的 where 子句中要求一个特定值,并且您要求在内部查询,因此似乎数据库应该看到它并使用外部查询中的相同文字值。

实际上,内部查询只是在不知道p.partner_id 的可能值的情况下首先运行,因此出现“多行”错误。

【讨论】:

  • 这是一个很好的解释。那么我上面的查询和你在这里的查询到底有什么区别:stackoverflow.com/questions/349933/…
  • 我没有任何线索。我最好的猜测是我的另一个答案是完全错误的,我当时忽略了它。
  • 我试图找到该查询的测试运行,但我找不到。因此,如果我不对其进行测试,它很可能从一开始就不起作用。很抱歉没有帮助。 :(
【解决方案2】:

当您使用 = 运算符与子查询的结果进行比较时,您的子查询可能只返回一行。 如果要检查子查询返回的所有行,则必须使用 IN 运算符。

AND u.User_Id IN ( SELECT .... )

【讨论】:

  • 您的回答本身并没有错,只是没有回答所提出的问题。你的回答只是让我用不同的方式表达我原来的问题......“为什么子查询在第二种情况下返回多行,而不是第一种?
  • 可能是因为查询优化器将“LIMIT ...”视为在展开和优化关系后要评估的内容。它太间接了,无法识别您的表达式只能产生一行,因此它希望表达式就好像集合计数是未知的一样。
  • 这确实是一种尴尬的查询形式。尽量不要将 LIMIT 和 ORDER BY 之类的东西放入子查询中。
【解决方案3】:

当您更改子查询中的 where 子句时,您将打开闸门。主查询中的 where 子句不限制子查询。所以你得到的结果不止 1 个。

编辑:这是什么数据库?我之前没有遇到过“使用”构造......

【讨论】:

    【解决方案4】:

    @Jason Punyon mysql 支持 USING 构造。

    【讨论】:

      猜你喜欢
      • 2012-05-19
      • 1970-01-01
      • 2012-12-28
      • 1970-01-01
      • 2021-11-30
      • 2012-03-12
      • 2019-02-04
      • 2013-04-22
      • 1970-01-01
      相关资源
      最近更新 更多