'Short-circuit UNION? (only execute 2nd clause if 1st clause has no results)
If I do:
SELECT * FROM A
WHERE conditions
UNION
SELECT * FROM B
WHERE conditions
I get the union of the resultset of query of A and resultset of query of B.
Is there a way/operator so that I can get a short-circuit OR
result instead?
I.e. Get the result of SELECT * FROM A WHERE conditions
and only if this returns nothing get the resultset of the SELECT * FROM B WHERE conditions
?
Solution 1:[1]
The short answer is no, but you can avoid the second query, but you must re-run the first:
SELECT * FROM A
WHERE conditions
UNION
SELECT * FROM B
WHERE NOT EXISTS (
SELECT * FROM A
WHERE conditions)
AND conditions
This assumes the optimizer helps out and short circuits the second query because the result of the NOT EXISTS is false for all rows.
If the first query is much cheaper to run than the second, you would probably gain performance if the first row returned rows.
Solution 2:[2]
You can do this with a single SQL query as:
SELECT *
FROM A
WHERE conditions
UNION ALL
SELECT *
FROM B
WHERE conditions and not exists (select * from A where conditions);
Solution 3:[3]
Have you tried an 'If' Statement?
If(select Count(*) from A where conditions) > 0
Then Select * from A where conditions
Else Select * from B where conditions
Solution 4:[4]
I did not need to check against the return of "nothing" in the first union block, but against "x number of rows".
Just sharing this for those who might search for this here as well, and taking up the accepted answer here + the answer of this user.
You can check against the count of the rows of the "first block of the union"-subquery like this:
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
I could use it like this, but I did not check this pseudocode thoroughly against my use case, no guarantees that this is 100% right.
In your case, you would not use it anyway, but you could, taking 0
instead of 5
, and you would need a limit 0,1
to check against 0
rows. The limit 0,1
speeds up such rows-count checks against > 0
or in my case a rows-count check for = 1
.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Gordon Linoff |
Solution 3 | orgtigger |
Solution 4 |