Question

I would like to do an iterative SQL query as a way to find records within a database. The table names are long and annoying, but I'll try to get it down to a minimal example. I'm searching a table of cars for cars with certain characteristics. Normally, this would be very easy:

SELECT vin FROM cars WHERE color = 'red' AND interior = 'cloth'

However, the user can choose a 'No Preference' option, in which case I don't want to filter by that characteristic. I get around this with conditional subqueries, where @color is defined by user input:

SELECT vin FROM cars WHERE id IN
 (SELECT CASE
   WHEN @color = 'No Preference' THEN id
   WHEN color = @color THEN id)
AND id IN
 (SELECT CASE
   WHEN @interior = 'No Preference' THEN id
   WHEN interior = @interior THEN id)

This works because it selects the set of all records when anything is 'No Preference' (which, as I AND everything together, will make sure I do not lose any).

However, it is necessary now to filter by many car specifications, and although I could write all of these subqueries and then AND them together, I feel like I should be able to do it in a smarter fashion. From what I understand, iteration in SQL is easy to do; just create a table holding all the car specs that <> 'No Preference' and iterate over them.

This works just fine with my developer database access. However, queries made by accounts end user credentials do not have CREATE or DROP permissions, so table creation is not an option for me here.

Is there a way I can iteratively do these subqueries, without creating a new table?

Was it helpful?

Solution

It sounds like you want to build a dynamic sql statement based on your inputs. Something like:

DECLARE @sqlstmt VARCHAR(MAX)
SET @sqlstmt = 'SELECT vin FROM cars WHERE 1=1'
IF @interior<>'No Preference'
   SET @sqlstmt = @sqlstmt + ' AND interior = '''+@interior+'''
IF @color<>'No Preference'
   SET @sqlstmt = @sqlstmt + ' AND color = '''+@color+'''
...
exec(@sqlstmt)

Obviously, you'll need to filter against sql injection, but this logic should get you started.

OTHER TIPS

No. Iteration in SQL is bad idea. SQL manipulates with sets. You can build your predicate by this easy pattern.

WHERE
     (interior = @interior OR @interior = 'No Preference')
 AND (color = @color OR @color = 'No Preference')
 ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top