2

Oracle here. I have the following table:

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

In my code I will be given a string called fizzOrBuzz, and I will not know which field (fizz or buzz) it will be ahead of time. I need to search the Foobars table for either a matching fizz or buzz based on the fizzOrBuzz value. The only thing that is certain is that there are no duplicates (no 2 records will have the same fizz value, and no 2 records will have the same buzz value).

My query thus far:

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  
)

However this isn't valid SQL code (doesn't execute) and I'm sure there's a better way of doing this altogether. Any ideas?

2
  • OR => OR EXISTS ? But the other options offered as answers are be better; not least because your subqueries aren't correlated - assuming you're expecting the ID from those to match the main query. (It's helpful to show the error you got, and sample data/expected results.) Commented Aug 16, 2019 at 15:03
  • Does the fizz column actually contain the string "fizz"? Commented Aug 16, 2019 at 15:23

4 Answers 4

6

Why not just use OR?

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

Or, just use one parameter with IN:

select id
from foobars
where ? in (fizz, buzz);
Sign up to request clarification or add additional context in comments.

Comments

4

I'm not sure why you need exists, surely a basic or works here:

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

Comments

2

You could use UNION:

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

5 Comments

Writing query in this manner in Oracle does not make sense. You might want to read about Oracle query transformations and OR-expansion in particular.
@DrYWit . . . You should be a little more informative with such a comment. Is the issue the UNION? Would it be fixed by using UNION ALL? Are you assuming there are indexes on the fizz and buzz columns?
@DrYWit The query itself is perfectly valid and I know what a OR-expansion is. Please note I am using UNION and not UNION ALL
@GordonLinoff, if someone uses OR then CBO can transform a query to the form which is more efficient based on statistics, presence of indexes etc. With UNION Oracle will always access table twice; not to mention that, yes, UNION ALL must be used instead of UNION. And for those who are interested: blogs.oracle.com/optimizer/…
@LukaszSzozda, the query you provide does not have any advantage in compare to version with 'OR' but has a number of drawbacks instead and should never be recommended even though it's "perfectly valid". I hope it's clear.
1

You can simply use OR

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

Cheers!!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.