Mysql

MySQL 中 WHERE 子句中的 CASE

  • March 7, 2019

我正在一個使用 MySQL 的項目中工作,並使用儲存過程來進行我的 SELECT 查詢,所以它們都具有相同的結構:

DELIMITER $$
CREATE PROCEDURE `case_in_where`(IN `column_selector` INT, IN `value` VARCHAR(255)) 
   BEGIN

   SELECT * FROM `foo`
   WHERE 
       CASE
           WHEN `column_selector` IS NULL THEN 1 
           WHEN `column_selector` = 1 THEN `foo`.`column_1` = `value`
           WHEN `column_selector` = 2 THEN `foo`.`column_2` = `value`
       END
   ;
END $$
DELIMITER ; 

但我看到,當人們使用這種方法尋求幫助時,通常的答案是它應該使用 AND、OR 或 Dynamic SQL。那麼,這種方式不正確嗎?這是一種不好的做法還是在性能上有什麼不同?

我應該使用 AND、OR 或 Dynamic SQL 還是針對每種情況進行不同的查詢?

預先感謝。

通常答案是它應該使用 AND、OR 或 Dynamic SQL。

您的程式碼中沒有動態 SQL。

性能上有什麼區別嗎?

當然,您顯示的結構會導致全掃描並且無法優化。但是使用邏輯運算符建構的條件也無法正常優化。要獲得最高性能,請使用具有 3 個獨立子查詢的 UNION ALL,每個子查詢一個條件。因為其中兩個的常數評估條件將給出錯誤,所以在實踐中只有三個子查詢中的一個會被執行。

在 SP 中,這可以是用外部 CASE 包裝的 3 個單獨的查詢:

DELIMITER $$;
CREATE PROCEDURE `case_in_where`(IN `column_selector` INT, IN `value` VARCHAR(255)) 
   BEGIN
   CASE WHEN `column_selector` IS NULL THEN 
            SELECT * FROM `foo`;
        WHEN `column_selector` = 1 THEN 
            SELECT * FROM `foo` WHERE `foo`.`column_1` = `value`;
        WHEN `column_selector` = 2 THEN 
            SELECT * FROM `foo` WHERE `foo`.`column_2` = `value`;
   END CASE;
END $$;
DELIMITER ; 

流控制語句 - CASE 語法

引用自:https://dba.stackexchange.com/questions/231510