【问题标题】:Short-circuit UNION? (only execute 2nd clause if 1st clause has no results)短路联合? (如果第一个子句没有结果,只执行第二个子句)
【发布时间】:2013-09-03 22:22:53
【问题描述】:

如果我这样做:

SELECT * FROM A   
WHERE conditions  
UNION  
SELECT * FROM B   
WHERE conditions 

我得到A的查询结果集 B的查询结果集的并集。

有没有办法/操作员让我可以得到短路OR 结果?

即获取SELECT * FROM A WHERE conditions 的结果,并且 如果不返回任何内容,则获取SELECT * FROM B WHERE conditions 的结果集?

【问题讨论】:

    标签: mysql sql set union resultset


    【解决方案1】:

    简短的回答是否定的,但您可以避免第二次查询,但您必须重新运行第一次:

    SELECT * FROM A   
    WHERE conditions  
    UNION  
    SELECT * FROM B   
    WHERE NOT EXISTS (
        SELECT * FROM A   
        WHERE conditions)
    AND conditions
    

    这假设优化器帮助并缩短第二个查询,因为 NOT EXISTS 的结果对于所有行都是错误的。

    如果第一个查询的运行成本比第二个低得多,那么如果第一行返回行,您可能会获得性能。

    【讨论】:

      【解决方案2】:

      您可以使用单个 SQL 查询来做到这一点:

      SELECT *
      FROM A   
      WHERE conditions  
      UNION ALL
      SELECT *
      FROM B   
      WHERE conditions and not exists (select * from A where conditions);
      

      【讨论】:

        【解决方案3】:

        您是否尝试过“如果”语句?

        If(select Count(*) from A where conditions) > 0 
        Then Select * from A where conditions
        Else Select * from B where conditions
        

        【讨论】:

          【解决方案4】:

          我不需要检查第一个联合块中“无”的返回,而是检查“x 行数”。

          只是分享给那些可能在这里搜索的人,并在这里接受接受的答案+this user的答案。

          您可以像这样检查“联合的第一个块”子查询的行数:

          select col_b from (
          (
              SELECT * FROM A   
              WHERE conditions
              ORDER BY 
              LIMIT (0,5)
          ) 
          UNION
          (
              SELECT * FROM B   
              WHERE 5 not in (
                  select count(1) from (
                      SELECT * FROM A   
                      WHERE conditions
                      limit 0,5) tbl_sub
                  )
              AND conditions
              ORDER BY col_a
              LIMIT (0,5)
          )
          ) tbl
          

          我可以这样使用它,但我没有根据我的用例彻底检查这个伪代码,不能保证这是 100% 正确的。

          在您的情况下,无论如何您都不会使用它,但您可以使用0 而不是5,并且您需要limit 0,1 来检查0 行. limit 0,1 加速了针对 > 0 的此类行数检查,或者在我的情况下是针对 = 1 的行数检查。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-08-23
            • 2013-02-10
            • 2021-08-04
            • 1970-01-01
            • 1970-01-01
            • 2015-03-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多