CASE WHEN 是 MySQL 中實現條件邏輯、數據轉換、動態分組的核心函數,支援簡單/搜尋/嵌套三種形式。本文通過建表、插數、多維案例全面講解。
CREATE TABLE lee (
id INT PRIMARY KEY AUTO_INCREMENT,
name CHAR(20),
birthday DATETIME
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO lee(name,birthday) VALUES
('sam','1990-01-01'), ('lee','1980-01-01'), ('john','1985-01-01');
SELECT name,
CASE
WHEN birthday < '1981' THEN 'old'
WHEN birthday > '1988' THEN 'young'
ELSE 'ok'
END AS age_group
FROM lee;
結果:lee→old, john→ok, sam→young
SELECT name,
CASE name
WHEN 'sam' THEN 'young'
WHEN 'lee' THEN 'handsome'
ELSE 'good'
END AS tag
FROM lee;
SELECT name, birthday,
CASE
WHEN birthday > '1983' THEN 'young'
WHEN name = 'lee' THEN 'handsome'
ELSE 'just so so'
END AS remark
FROM lee;
CREATE TABLE penalties (
paymentno INT PRIMARY KEY,
payment_date DATE,
amount DECIMAL(7,2)
);
INSERT INTO penalties VALUES
(1,'2008-01-01',3.45), (2,'2009-01-01',50.45), (3,'2008-07-01',80.45);
SELECT payment_date, amount,
CASE
WHEN amount >= 0 AND amount < 40 THEN 'low'
WHEN amount >= 40 AND amount < 80 THEN 'moderate'
WHEN amount >= 80 THEN 'high'
ELSE 'null'
END AS level
FROM penalties;
SELECT * FROM (
SELECT paymentno, amount,
CASE
WHEN amount >= 0 AND amount < 40 THEN 'low'
WHEN amount >= 40 AND amount < 80 THEN 'moderate'
WHEN amount >= 80 THEN 'high'
ELSE 'incorrect'
END AS lvl
FROM penalties
) AS p WHERE p.lvl = 'low';
SELECT DISTINCT a.PatientID, a.PatientName,
CASE
WHEN b.usedstartTime IS NOT NULL AND b.UsedEndTime IS NULL THEN '1' -- 使用中
WHEN b.usedstartTime IS NOT NULL AND b.UsedEndTime IS NOT NULL THEN '2' -- 已歸還
END AS usedState
FROM mets_v_patient_baseinfo a
LEFT JOIN mets_devices_used_history b ON a.PatientID = b.PatientID
WHERE (SELECT IFNULL(IsDeleted,0) FROM userpublic_info WHERE UserID = a.PatientID) = 0
ORDER BY PatientID DESC LIMIT 15;
birthday > '1988' 視字典序,建議用 YEAR(birthday) > 1988。ELSE 'default' 避免應用層誤判。SUM(CASE WHEN sex='M' THEN 1 ELSE 0 END) AS male_cnt 實現條件計數。CASE WHEN 優化MySQL 8.0 優化器對 CASE WHEN 常量折疊、索引下推有更好支援,複雜條件下執行計劃更穩定。