简体   繁体   English

SQL Where子句中的条件运算符

[英]Conditional Operator in SQL Where Clause

I'm wishing I could do something like the following in SQl Server 2005 (which I know isnt valid) for my where clause. 我希望我可以在SQl Server 2005中为我的where子句做类似以下的事情(我知道这是无效的)。 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. 有时@teamID(传递到存储过程中)将是现有teamID的值,否则它将始终为零,并且我需要Team表中的所有行。

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. 我使用Case进行了研究,运算符需要放在整个语句之前或之后,这使我无法基于@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 

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)

Without using dynamic SQL, the most performant option is: 不使用动态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

Using Dynamic SQL: 使用动态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. 请注意sp_EXECUTESQL缓存查询计划,而EXEC不会。 Read this: http://www.sommarskog.se/dynamic_sql.html 阅读此: http : //www.sommarskog.se/dynamic_sql.html

关于什么:

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

Even simpler than Andomar's answer, and assuming that id is never 0 (as for most auto-increment ids) is 比Andomar的答案更简单,并且假设id永远不会为0(对于大多数自动递增的id)

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. 当@teamid为零时,该谓词始终为true,否则仅当它与特定行的teamId匹配时为true。

Note however: this works pretty efficiently on Sybase 11 or above; 但是请注意:这在Sybase 11或更高版本上非常有效。 it worked pretty inefficiently on MS SQL server 2003; 它在MS SQL Server 2003上的工作效率很低; I don't know how it works on the current version of MS SQL Server. 我不知道它在当前版本的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. 您只需要将案例放在where子句中,而不是案例中的where子句中。 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. 我上面给出的表格更有可能由智能查询优化器重写(您的里程取决于您的RDBMS),以在@teamid不为零时使用索引。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM