簡體   English   中英

SQL - WHERE中的CASE表達式

[英]SQL - CASE expression inside WHERE

我在這里閱讀了有關在WHERE子句中使用CASE表達式的內容:

http://scottelkin.com/sql/using-a-case-statement-in-a-sql-where-clause/

我正在嘗試使用它來根據用戶應用程序傳遞的合同號來過濾select語句的結果。 我的代碼當前拋出了'無效參數'的錯誤,無論傳入什么。我驗證SELECT / FROM工作正常,如沒有CASE表達式的WHERE子句。 這是我的代碼。

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END =
tblContracts.ContractNo)

代碼的冗余用於故障排除,我打算稍后在CASE上使用通配符過濾。 我正專注於立即降低語法。 我相信這應該返回參數與表中存儲的合同號匹配的所有記錄。 任何幫助或建議將不勝感激。

你確定你要這么做嗎? 你的case語句總是返回@ContractNo 我認為你在尋找的是:

where 
    case @ContractNo 
        when 0 then tblContracts.ContractNo 
        else @ContractNo 
    end = tblContracts.ContractNo

上面的過濾器說“給我合同,其中ContractNo等於參數,或者如果參數為0,則給出所有ContractNo

僅過濾合同編號字段與參數完全相等的前一過濾器。

無論如何,你應該這樣做:

where @ContractNo = 0 or @ContractNo = tblContracts.ContractNo

邏輯更容易理解,除此之外(不要引用我),優化器可能會在case語句之外更好地工作。

閱讀完解釋后,有一種更好的方法可以在沒有CASE下執行此操作:

WHERE @ContractNo = 0 OR tblContracts.ContractNo = @ContractNo

這將僅返回匹配的合同號,除非@ContractNo為0,在這種情況下,它將返回所有記錄。

編輯:我剛剛注意到casperOne提出了同樣的事情 我沒有看到。 大自己。

試着省略錯誤位置的括號 - 正確的一個應該在“結束”之后。

也許你忘了宣布@ContractNo? 它是否與0和tblContracts.ContractNo相當?

將你的右括號移到=之前,如下所示:

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END)=tblContracts.ContractNo

我沒有看到這個案例陳述會做什么但是...如果@ContractNo = 0或者它不是......你會返回相同的東西......

正確的語法是:

  Select...
  ...
  Where(
    Case
      When <Condition>
        Then <Return if true>
        Else <Return if false>
      End
 ) = <Whatever is being matched to the output of the case statement>

不管語法如何,你的例子沒有多大意義,如果你正在尋找匹配或者合同號為0的所有項目,那么你會這樣做:

Select...
...
Where (
  @ContractNo = 0 Or
  @ContractNo = tblContracts.ContractNo
)

這似乎比你試圖使用case語句更有意義。

編輯:我一定是誤解了這個問題 - 缺少的參數通常意味着參數(在本例中為@ContractNo)未在查詢/過程的范圍內聲明。 但是有人已經指出了這一點,所以我不能相信這一點。

case語句的原因,包括整個“If it為0,給出參數,否則,只給出參數”是為了測試它以試圖使語法正確。 最初,我試過說“如果它是0,然后傳入'%',返回每個值。我在那里發布的代碼是因為我一直得到'無效參數'並且認為我的語法一定有問題。我把它分成基本的參數匹配,像這樣,

WHERE @ContractNo = tblContracts.ContractNo

它返回記錄很好。 讓我解釋一下。

我從一堆不同的表中提取,並使用select語句中未包含的信息過濾內容(即tblContracts沒有通過Select從中提取信息,它僅在Where中使用)。 用戶將從具有不同合同號的組合框中進行選擇,以及默認值“全部”。

當組合框的索引發生變化時,我將發生一個事件。 如果它是'All',0將作為參數傳入,我不想進行過濾。 否則,我只想要該合同號的信息(Else @ContractNo的原因)。

Recursive的帖子正好解決了我的問題。

我看到有關我原帖的清晰度的投訴。 在未來,我能做些什么才能讓我說的更直接? 我不習慣於對代碼的問題進行措辭,並為任何混亂的事情道歉。 我是否只需要在第二篇文章中提供擴展的詳細信息?

再次感謝所有的幫助。

你的意思不是這樣嗎?

SELECT * 
    FROM tblContracts
    WHERE     
    CASE 
       WHEN tblContracts.ContractNo = 0 THEN @ContractNo 
       ELSE tblContracts.ContractNo
    END = tblContracts.ContractNo

其中@ContractNo是與tblContracts.ContractNo相同的數據類型的變量

為什么你甚至需要一個案例陳述?

當@ContractNo = 0然后(0 = tblContracts.ContractNo)否則@ContractNo然后(@ContractNo = tblContracts.ContractNo)

這沒有任何意義,因為你可以簡單地寫這個

其中@contractNo = tblContracts.contractNo

合同號實際上是數字還是字符串總是恰好是數字。 檢查表與參數和CASE語句之間的數據類型(例如,“= 0”或“='0'”)

這個語法應該有效(在Oracle中)

WHERE CASE WHEN tblContracts.ContractNo = 0 
           THEN @ContractNo 
           ELSE tblContracts.ContractNo
      END = tblContracts.ContractNo

當你說:

我從一堆不同的表中提取,並使用select語句中未包含的信息過濾內容(即tblContracts沒有通過Select從中提取信息,它僅在Where中使用)。 用戶將從具有不同合同號的組合框中進行選擇,以及默認值“全部”。

然后聽起來應該有一個“Where exists”條款。 既然你沒有從那張桌子中取出任何信息?!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM