使用case或if的SQL搜索

时间:2011-03-10 18:35:10

标签: sql sql-server-2005

到目前为止,每个人都是超级帮助。我的下一个问题是对我来说最好的方法是什么...如果我有7个字段,用户可以搜索进行此搜索的最佳方式,它们可以包含7个字段的任意组合,这样就可以了7个字段。 !或5040组合,这是不可能编码那么多。那么,当用户选择字段1和字段3或者选择字段1,字段2和字段7时,如何计算?使用SQL有什么容易做到的吗?我不知道我是否应该使用IF语句来解决这个问题,或者在select语句中转向CASE。或者我应该走一个完全不同的方向?好吧,如果有人有任何有用的指示我会非常感激。

谢谢

5 个答案:

答案 0 :(得分:2)

您可能希望考虑使用动态SQL。有关此主题的优秀文章,请参阅:Dynamic Search Conditions in T-SQLCatch-all queries

答案 1 :(得分:0)

Select f1,f2  from table where f1 like '%val%' or f2 like '%val%'

答案 2 :(得分:0)

可以编写一个接受每个参数为null的存储过程,然后编写WHERE子句,如:

WHERE (field1 = @param1 or @param1 is null) 
AND (field2 = @param2 or @param2 is null) etc...

但我不推荐它。它肯定会影响性能,这取决于您拥有的参数数量。在这种情况下,我第二次看到Joe Stefanelli回答dynamic SQL

答案 3 :(得分:0)

取决于:

  • 您的数据如何,
  • 他们有多大,
  • 预期的结果如何(所有匹配的记录或前100名就足够了),
  • 您有多少资源数据库。
你可以尝试类似的东西:

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

我在大型数据库(数百万条记录,但在大型服务器上运行)上使用此技术来过滤某些预定义数据中的数据。而且效果很好。

但是我不需要所有匹配的记录 - 取决于查询10-3000匹配记录就足够了。

答案 4 :(得分:-1)

如果您使用的是存储过程,则可以使用此方法:

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 

这些通常称为可选参数。我们的想法是,如果你没有传递一个,则获取默认值(null),并且where子句的那一部分总是返回true。