首頁 > 資料庫 > mysql教程 > 如何在SQL Server 2008中正確使用WHERE子句中的CASE語句?

如何在SQL Server 2008中正確使用WHERE子句中的CASE語句?

Mary-Kate Olsen
發布: 2025-01-11 09:54:42
原創
771 人瀏覽過

How Can I Correctly Use CASE Statements Within WHERE Clauses in SQL Server 2008?

解決 SQL Server 2008 WHERE 子句中的 CASE 語句問題

在 SQL Server 2008 的 WHERE 子句中使用 CASE 語句可能會帶來困難。 以下查詢舉例說明了一個常見問題:

<code class="language-sql">SELECT
    tl.storenum 'Store #', 
    co.ccnum 'FuelFirst Card #', 
    co.dtentered 'Date Entered',
    CASE st.reasonid 
        WHEN 1 THEN 'Active' 
        WHEN 2 THEN 'Not Active' 
        WHEN 0 THEN st.ccstatustypename 
        ELSE 'Unknown' 
    END 'Status',
    CASE st.ccstatustypename 
        WHEN 'Active' THEN ' ' 
        WHEN 'Not Active' THEN ' ' 
        ELSE st.ccstatustypename 
    END 'Reason',
    UPPER(REPLACE(REPLACE(co.personentered,'RT\\',''),'RACETRAC\\','')) 'Person Entered',
    co.comments 'Comments or Notes'
FROM 
    comments co
    INNER JOIN cards cc ON co.ccnum=cc.ccnum
    INNER JOIN customerinfo ci ON cc.customerinfoid=ci.customerinfoid
    INNER JOIN ccstatustype st ON st.ccstatustypeid=cc.ccstatustypeid
    INNER JOIN customerstatus cs ON cs.customerstatuscd=ci.customerstatuscd
    INNER JOIN transactionlog tl ON tl.transactionlogid=co.transactionlogid
    LEFT JOIN stores s ON s.StoreNum = tl.StoreNum
WHERE 
    CASE LEN('TestPerson')
        WHEN 0 THEN co.personentered  = co.personentered
        ELSE co.personentered LIKE '%TestPerson'
    END 
    AND cc.ccnum = CASE LEN('TestFFNum')
        WHEN 0 THEN cc.ccnum 
        ELSE 'TestFFNum' 
    END 
    AND CASE LEN('2011-01-09 11:56:29.327') 
        WHEN 0 THEN co.DTEntered = co.DTEntered 
        ELSE 
            CASE LEN('2012-01-09 11:56:29.327') 
                WHEN 0 THEN co.DTEntered >= '2011-01-09 11:56:29.327' 
                ELSE co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327' 
            END 
    END
    AND tl.storenum < 699 
ORDER BY tl.StoreNum</code>
登入後複製

解:用布林邏輯重構

核心問題在於 WHERE 子句的條件邏輯中直接使用了 CASE 語句。 CASE 表達式應該產生一個值;它們不應該是全部情況。

解決方案涉及使用 ANDOR 運算子將 CASE 語句替換為等效的布林邏輯:

<code class="language-sql">SELECT
    tl.storenum 'Store #', 
    co.ccnum 'FuelFirst Card #', 
    co.dtentered 'Date Entered',
    CASE st.reasonid 
        WHEN 1 THEN 'Active' 
        WHEN 2 THEN 'Not Active' 
        WHEN 0 THEN st.ccstatustypename 
        ELSE 'Unknown' 
    END 'Status',
    CASE st.ccstatustypename 
        WHEN 'Active' THEN ' ' 
        WHEN 'Not Active' THEN ' ' 
        ELSE st.ccstatustypename 
    END 'Reason',
    UPPER(REPLACE(REPLACE(co.personentered,'RT\\',''),'RACETRAC\\','')) 'Person Entered',
    co.comments 'Comments or Notes'
FROM 
    comments co
    INNER JOIN cards cc ON co.ccnum=cc.ccnum
    INNER JOIN customerinfo ci ON cc.customerinfoid=ci.customerinfoid
    INNER JOIN ccstatustype st ON st.ccstatustypeid=cc.ccstatustypeid
    INNER JOIN customerstatus cs ON cs.customerstatuscd=ci.customerstatuscd
    INNER JOIN transactionlog tl ON tl.transactionlogid=co.transactionlogid
    LEFT JOIN stores s ON s.StoreNum = tl.StoreNum
WHERE 
    (LEN('TestPerson') = 0 AND co.personentered = co.personentered) OR (LEN('TestPerson') > 0 AND co.personentered LIKE '%TestPerson')
    AND ((LEN('TestFFNum') = 0 AND cc.ccnum = cc.ccnum) OR (LEN('TestFFNum') > 0 AND cc.ccnum = 'TestFFNum'))
    AND ((LEN('2011-01-09 11:56:29.327') = 0 AND co.DTEntered = co.DTEntered) OR (LEN('2012-01-09 11:56:29.327') = 0 AND co.DTEntered >= '2011-01-09 11:56:29.327') OR (co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327'))
    AND tl.storenum < 699
ORDER BY tl.StoreNum;</code>
登入後複製

效能增強

雖然這個更正後的查詢可以正確運行,但效能還可以進一步提高:

  • 減少巢狀:深度嵌套的OR條件可能會降低效率。 考慮替代查詢結構(例如,使用 UNION ALL 表示不同的搜尋條件)。
  • 索引: 確保 WHERE 子句中經常使用的欄位上有索引(例如 co.personenteredcc.ccnumco.DTEnteredtl.storenum)。
  • 參數化:如果這些「測試」值是變量,請使用參數化查詢來避免重複查詢解析。

透過解決這些問題,您可以建立更有效率且可讀的 SQL 查詢。

以上是如何在SQL Server 2008中正確使用WHERE子句中的CASE語句?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板