Conditional Operator in SQL Where Clause

僤鯓⒐⒋嵵緔 提交于 2019-12-18 07:52:08

问题


I'm wishing I could do something like the following in SQl Server 2005 (which I know isnt valid) for my where clause. Sometimes @teamID (passed into a stored procedure) will be the value of an existing teamID, otherwise it will always be zero and I want all rows from the Team table.

I researched using Case and the operator needs to come before or after the entire statement which prevents me from having a different operator based on the value of @teamid. Any suggestions other than duplicating my select statements.

    declare @teamid int
    set @teamid = 0

    Select Team.teamID From Team
      case @teamid
         when 0 then 
            WHERE Team.teamID > 0
         else
            WHERE Team.teamID = @teamid
      end 

回答1:


You can do that without a case:

SELECT  Team.teamID 
FROM    Team
WHERE   (@teamid = 0 AND Team.teamID > 0)
        OR (@teamid <> 0 AND Team.teamID = @teamid)



回答2:


Without using dynamic SQL, the most performant option is:

IF @teamid = 0
  BEGIN

    SELECT t.teamid
      FROM TEAM t
     WHERE t.teamid > 0

  END
ELSE
  BEGIN

    SELECT t.teamid
      FROM TEAM t
     WHERE t.teamid = @teamid

  END

Using Dynamic SQL:

DECLARE @SQL NVARCHAR(4000)
   SET @SQL = 'SELECT t.teamid
                 FROM TEAM t
                WHERE 1 = 1 '

   SET @SQL = @SQL + CASE @teamid
                       WHEN 0 THEN ' AND t.teamid > 0 '
                       ELSE ' AND t.teamid = @teamid '
                     END

BEGIN

  EXEC sp_EXECUTESQL @SQL N'@teamid INT', @teamid

END

Beware that sp_EXECUTESQL caches the query plan, while EXEC will not. Read this: http://www.sommarskog.se/dynamic_sql.html




回答3:


What about:

Select Team.teamID From Team Where (@teamid=0 and team.teamID>0) or (@teamid<>0 and team.teamid=@teamid)



回答4:


Even simpler than Andomar's answer, and assuming that id is never 0 (as for most auto-increment ids) is

SELECT  Team.teamID 
FROM    Team
WHERE   @teamid = 0 or Team.teamID = @teamid;

That predicate is always true when @teamid is zero, and otherwise only true when it matches a particular row's teamId.

Note however: this works pretty efficiently on Sybase 11 or above; it worked pretty inefficiently on MS SQL server 2003; I don't know how it works on the current version of MS SQL Server.

Also, you can use case; you just have to put the case in where clause, not the where clause in the case. So your original query would be:

Select Team.teamID 
From Team
where 
   case when @teamid = 0 then 0 else Team.teamID end = @teamId;

Note that this is likely to be less efficient, however, as it must be evaluated per row and will also likely result in a full table scan.

The form I gave above is more likely to be rewritten by a smart query optimizer (your mileage depends on your RDBMS) to use an index when @teamid is not zero.




回答5:


If you could treat Null as all records:

WHERE Team.teamID = ISNULL(@teamid, Team.teamID)


来源:https://stackoverflow.com/questions/2568775/conditional-operator-in-sql-where-clause

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!