【问题标题】:Conditional WHERE EXISTS in Oracle queryOracle 查询中的条件 WHERE EXISTS
【发布时间】:2019-08-16 14:58:46
【问题描述】:

这里是甲骨文。我有下表:

create table Foobars ( 
    id integer constraint pkFoobars primary key using index,
    fizz varchar2(20 char), 
    buzz varchar2(20 char)
)

在我的代码中,我将得到一个名为fizzOrBuzz 的字符串,我不会提前知道哪个字段(fizzbuzz)。我需要根据fizzOrBuzz 值在Foobars 表中搜索匹配的fizzbuzz。唯一可以确定的是没有重复(没有 2 条记录具有相同的 fizz 值,也没有 2 条记录具有相同的 buzz 值)。

到目前为止我的查询:

SELECT
  id
FROM
  Foobars
WHERE EXISTS (
  SELECT
    id
  FROM
    Foobars
  WHERE
    fizz = ? -- fizzOrBuzz gets injected here by the app layer
) OR (
  SELECT
    id
  FROM
    Foobars
  WHERE
    buzz = ? -- fizzOrBuzz gets injected here by the app layer  
)

但是,这不是有效的 SQL 代码(不执行),我确信有更好的方法来完全做到这一点。有什么想法吗?

【问题讨论】:

  • OR => OR EXISTS ?但是作为答案提供的其他选项更好;尤其是因为您的子查询不相关 - 假设您期望这些子查询的 ID 与主查询匹配。 (显示您遇到的错误以及示例数据/预期结果会很有帮助。)
  • fizz 列是否实际包含字符串“fizz”?

标签: sql oracle


【解决方案1】:

为什么不直接使用OR

select id
from foobars
where fizz = ? or buzz = ?;

或者,只需将一个参数与IN 一起使用:

select id
from foobars
where ? in (fizz, buzz);

【讨论】:

    【解决方案2】:

    我不确定你为什么需要exists,当然基本的or 在这里工作:

    select id
    from   foobars
    where  fizz = ? -- fizzOrBuzz gets injected here by the app layer
    or     buzz = ? -- fizzOrBuzz gets injected here by the app layer  
    

    【讨论】:

      【解决方案3】:

      你可以使用UNION:

      SELECT id FROM Foobars WHERE fizz = ?
      UNION 
      SELECT id FROM Foobars WHERE buzz = ?
      

      【讨论】:

      • 在 Oracle 中以这种方式编写查询没有意义。您可能想阅读有关 Oracle 查询转换和 OR 扩展的特别信息。
      • @DrYWit 。 . .您应该对这样的评论提供更多信息。问题是UNION 吗?使用UNION ALL 会修复它吗?您是否假设 fizzbuzz 列上有索引?
      • @DrYWit 查询本身是完全有效的,我知道OR-expansion 是什么。请注意我使用的是UNION 而不是UNION ALL
      • @GordonLinoff,如果有人使用 OR,那么 CBO 可以根据统计信息、索引的存在等将查询转换为更有效的形式。UNION Oracle 将始终访问表两次;更不用说,是的,必须使用UNION ALL而不是UNION。对于那些感兴趣的人:blogs.oracle.com/optimizer/…
      • @LukaszSzozda,与带有“OR”的版本相比,您提供的查询没有任何优势,但有许多缺点,即使它“完全有效”也不应该推荐。我希望它很清楚。
      【解决方案4】:

      您可以简单地使用OR

      SELECT id FROM Foobars WHERE fizz = ? OR buzz = ?
      

      干杯!!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-04
        • 2023-01-25
        相关资源
        最近更新 更多