SQL Search using case or if
Everyone has开发者_JAVA百科 been a super help so far. My next question is what is the best way for me to approach this... If I have 7 fields that a user can search what is the best way to conduct this search, They can have any combination of the 7 fields so that is 7! or 5040 Combinations which is impossible to code that many. So how do I account for when the User selects field 1 and field 3 or they select field 1, field 2, and field 7? Is there any easy to do this with SQL? I dont know if I should approach this using an IF
statement or go towards a CASE
in the select statement. Or should I go a complete different direction? Well if anyone has any helpful pointers I would greatly appreciate it.
Thank You
You'll probably want to look into using dynamic SQL for this. See: Dynamic Search Conditions in T-SQL and Catch-all queries for good articles on this topic.
Select f1,f2 from table where f1 like '%val%' or f2 like '%val%'
You could write a stored procedure that accepts each parameter as null and then write your WHERE
clause like:
WHERE (field1 = @param1 or @param1 is null)
AND (field2 = @param2 or @param2 is null) etc...
But I wouldn't recommend it. It can definitely affect performance doing it this way depending on the number of parameters you have. I second Joe Stefanelli's answer with looking into dynamic SQL in this case.
Depends on:
- how your data looks like,
- how big they are,
- how exact result is expected (all matching records or top 100 is enough),
- how much resources has you database.
you can try something like:
CREATE PROC dbo.Search(
@param1 INT = NULL,
@param2 VARCHAR(3) = NULL
)
AS
BEGIN
SET NOCOUNT ON
-- create temporary table to keep keys (primary) of matching records from searched table
CREATE TABLE #results (k INT)
INSERT INTO
#results(k)
SELECT -- you can use TOP here to norrow results
key
FROM
table
-- you can use WHERE if there are some default conditions
PRINT @@ROWCOUNT
-- if @param1 is set filter #result
IF @param1 IS NOT NULL BEGIN
PRINT '@param1'
;WITH d AS (
SELECT
key
FROM
table
WHERE
param1 <> @param1
)
DELETE FROM
#results
WHERE
k = key
PRINT @@ROWCOUNT
END
-- if @param2 is set filter #result
IF @param2 IS NOT NULL BEGIN
PRINT '@param2'
;WITH d AS (
SELECT
key
FROM
table
WHERE
param2 <> @param2
)
DELETE FROM
#results
WHERE
k = key
PRINT @@ROWCOUNT
END
-- returns what left in #results table
SELECT
table.* -- or better only columns you need
FROM
#results r
JOIN
table
ON
table.key = r.k
END
I use this technique on large database (millions of records, but running on large server) to filter data from some predefined data. And it works pretty well.
However I don't need all matching records -- depends on query 10-3000 matching records is enough.
If you are using a stored procedure you can use this method:
CREATE PROCEDURE dbo.foo
@param1 VARCHAR(32) = NULL,
@param2 INT = NULL
AS
BEGIN
SET NOCOUNT ON
SELECT * FROM MyTable as t
WHERE (@param1 IS NULL OR t.Column1 = @param1)
AND (@param2 IS NULL OR t.COlumn2 = @param2)
END
GO
These are usually called optional parameters. The idea is that if you don't pass one in it gets the default value (null) and that section of your where clause always returns true.
精彩评论