【问题标题】: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 的行数检查。