【问题标题】:Same sub-query used multiple times in a single query在单个查询中多次使用相同的子查询
【发布时间】:2013-06-08 11:38:47
【问题描述】:

我正在运行一个查询,其中包含在 WHERE 子句中多次使用的 same 子查询。

我有一个包含两个字段client_idbuyer_id 的表格。

子查询返回要从结果中排除的日期列表。

这就是我使用它的方式。

SELECT
  id, client_id, buyer_id
FROM relation
WHERE
  client_id NOT IN (SELECT <some_id> FROM <some_table> WHERE ...)
  AND buyer_id NOT IN (SELECT <some_ids> FROM <some_table> WHERE ...)

这按预期工作,但令我困扰的是有两个相同的子查询。我想知道是否有一种方法可以让我使用一次并将结果用于两个地方。

谢谢。

【问题讨论】:

  • 您是否尝试用 JOIN 替换该子查询?
  • @bluefeet,我已经大大简化了这个查询,只是为了给你真正的问题。我也无法理解JOINON 子句会是什么样子。

标签: mysql sql subquery


【解决方案1】:

表格查询:

select ...
from <main query>
where <select field> not in (select <subquery field> from <subquery>)

通常可以改写为:

select <main query fields>
from <main query>
left join <subquery> on <select field> = <subquery field>
where <subquery field> is null

如果您使用的子查询对于client_id 和buyer_id完全相同相同,因此应该可以将您的查询重新表述为:

SELECT id, client_id, buyer_id
FROM relation
LEFT JOIN <some_table> ON <some_id> IN (client_id, buyer_id)
WHERE <some_id> IS NULL

- 因此在查询中只有效地使用子查询一次。

【讨论】:

  • 带有连接的解决方案可能不会返回与带有子查询的解决方案相同的结果。
  • 正是我所经历的。它不是返回同一行,而是返回更多行。也需要额外的时间。我的原始查询在 41 秒内运行,而当我在 JOIN 中使用它时,花了 61 秒。
  • @TalhaAhmedKhan 你能提供一个SQL-Fiddle 一些数据吗?我确实认为这个查询等同于您所拥有的(如果 client_idbuyer_id 列不可为空。)
  • @ypercube,基本上我已经将我的查询简化了很长一段时间来向您展示问题所在,我的原始查询中有 3 个 INNER 和 4 个 LEFT JOIN 和大 WHERE 子句。如果你觉得这没问题,我会尝试只把提到的查询放在小提琴上。
  • 我不介意,但如果问题在于效率,那么我认为您不会避免发布完整的查询。
【解决方案2】:

您的查询可以转换如下:

SELECT
  id, client_id, buyer_id
FROM relation
LEFT JOIN some_table
) AS subquery ON ( subquery.some_id IN (client_id, buyer_id) AND <condition that was in your subquery>)
WHERE subquery.some_id IS NULL;

但我感觉这在执行时间方面仍然会表现得很糟糕。

考虑构建一个临时表来保存子查询的内容。

【讨论】:

    【解决方案3】:

    尝试将获取的值放入单独的数据库表中会有所帮助,这样当您已经将结果放在单独的表中时,现在可以确定是否存在相似的结果值或不同的结果值。等待听到你的诉讼......祝你好运。

    【讨论】:

      【解决方案4】:

      你可以用NOT EXISTS写这个:

      SELECT
          id, client_id, buyer_id
      FROM relation AS r
      WHERE NOT EXISTS
            ( SELECT 1 
              FROM <some_table> 
              WHERE (r.client_id = <some_id> OR r.buyer_id = <some_id>) 
                AND ...
            ) ;
      

      【讨论】:

      • 我在类似的查询中收到Error correlating field 异常。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多