SQL语句中的条件运算符

时间:2010-04-02 19:37:05

标签: sql sql-server sql-server-2005 tsql

我希望我可以在我的where子句中执行SQl Server 2005(我知道它无效)中的以下内容。有时@teamID(传入存储过程)将是现有teamID的值,否则它将始终为零,我想要Team表中的所有行。

我研究了使用Case,并且运算符需要在整个语句之前或之后出现,这使得我无法根据@teamid的值使用不同的运算符。除了重复我的选择陈述之外的任何建议。

    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 

5 个答案:

答案 0 :(得分:18)

你可以在没有案件的情况下做到这一点:

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

答案 1 :(得分:5)

不使用动态SQL,性能最佳的选项是:

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

使用动态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

请注意sp_EXECUTESQL缓存查询计划,而EXEC则不会。阅读:http://www.sommarskog.se/dynamic_sql.html

答案 2 :(得分:2)

怎么样:

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

答案 3 :(得分:2)

比Andomar的答案更简单,并且假设id永远不为0(对于大多数自动增量ID)

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

当@teamid为零时,该谓词始终为true,否则仅当它与特定行的teamId匹配时才为真。

但请注意:这在Sybase 11或更高版本上非常有效;它在MS SQL Server 2003上的效率非常低;我不知道它在当前版本的MS SQL Server上是如何工作的。

另外,你可以使用案例;你只需将case放在where子句中,而不是case中的where子句。所以你的原始查询将是:

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

请注意,这可能效率较低,因为必须对每行进行评估,并且还可能导致全表扫描。

上面给出的表单更有可能被智能查询优化器(你的里程取决于你的RDBMS)重写,以便在@teamid不为零时使用索引。

答案 4 :(得分:0)

如果您可以将Null视为所有记录:

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