Reputation: 19572
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
?
Upvotes: 3
Views: 2228
Reputation: 9552
I did not need to check against the return of "nothing" in the first union block, but against "x number of rows".
I share this for those who might search for this here as well. I take up the accepted answer here + the other answer here 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
For me, it did work, I could strongly speed up a query, I think it was from 40 min to 1 min. Yet, for the sake of anonymizing and standardizing, I wrote this dense dummy code that I could not test but that is at least ready to be shared, with the caveat that I cannot say for sure that it works.
In your case, you would take 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
.
Upvotes: -1
Reputation: 425053
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.
Upvotes: 6
Reputation: 1269923
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);
Upvotes: 1
Reputation: 4122
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
Upvotes: 0