2010-04-02 70 views
7

我希望我可以在SQl Server 2005(我知道它無效)中爲我的where子句做類似下面的事情。有時@teamID(傳遞到存儲過程)將是現有teamID的值,否則它將始終爲零,並且我希望Team表中的所有行。SQL中的條件運算符子句條款

我研究了使用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 

回答

18

你可以做,沒有一個案例:

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

什麼:

Select Team.teamID From Team Where (@teamid=0 and team.teamID>0) or (@teamid<>0 and [email protected]) 
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

+1

不會認爲動態SQL或兩個IF塊的增加的複雜性是值得的,除非你查詢中國國家體育總會數據庫;-) – Andomar 2010-04-02 19:48:47

+0

但是,性能增益是值得的複雜性和維護成本損失? – tpdi 2010-04-02 20:47:18

+0

所有三個選項都有其優點和缺點 - 在Andomar的建議中錯過了一個括號,事情將無法按預期工作。 – 2010-04-02 22:38:56

0

如果你可以把空的所有記錄:

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

甚至比Andomar的回答更簡單,並假設ID是永遠不爲0(對於大多數自動遞增IDS)是

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

當@teamid爲零時,該謂詞始終爲true,否則只有在匹配特定行的teamId時才爲真。

但請注意:在Sybase 11或更高版本上,此功能非常有效;它在MS SQL Server 2003上效率非常低下;我不知道它如何在當前版本的MS SQL Server上工作。

另外,你可以使用大小寫;你只需要將案例放在where子句中,而不是case中的where子句。所以,你的原始查詢是:

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

注意,這很可能是低效率的,但是,因爲它必須每行進行評估,也將有可能導致全表掃描。

上面給出的表單更有可能被智能查詢優化器(您的里程取決於您的RDBMS)重寫,以便在@teamid不爲零時使用索引。

+0

+1你的第一個回答很棒。更簡單的可能是@teamid in(0,TeamID)'! – Andomar 2010-04-02 20:48:25

+0

謝謝!但是使用一個inlist可能不會導致優化。 – tpdi 2010-04-02 21:07:29

+0

列表中只是語法糖。在優化器看到它之前,我認爲'a(b,c)'擴展爲'a = b或a = c' – Andomar 2010-04-02 21:53:08