MySQL 流程控制函數 IF()、CASE 在查詢與預存程序中的實戰用法大全。
-- 以某日期為中心,前後各 5 天
SELECT * FROM news
WHERE DATE(adddate) BETWEEN '2011-04-20' - INTERVAL 5 DAY
AND '2011-04-20' + INTERVAL 5 DAY;
-- 列舉特定日期
SELECT * FROM news
WHERE DATE(adddate) IN ('2011-04-20','2011-04-15','2011-04-25');
SELECT id, IF(status=1, '啟用', '停用') AS status_desc FROM users;
-- 更新:存在則 +1,不存在則插入 (配合 INSERT ... ON DUPLICATE KEY UPDATE)
INSERT INTO counter (k, v) VALUES ('pv', 1)
ON DUPLICATE KEY UPDATE v = v + 1;
CREATE PROCEDURE upsert_user(
IN p_name VARCHAR(50), IN p_phone VARCHAR(20), IN p_email VARCHAR(100)
)
BEGIN
DECLARE v_cnt INT DEFAULT 0;
SELECT COUNT(*) INTO v_cnt FROM users WHERE phone = p_phone;
IF v_cnt > 0 THEN
UPDATE users SET name=p_name, email=p_email, login_at=NOW() WHERE phone=p_phone;
ELSE
INSERT INTO users (name, phone, email, login_at) VALUES (p_name, p_phone, p_email, NOW());
END IF;
END;
SELECT
substr(area_id,1,1) AS type,
substr(area_id,2) AS id,
CASE substr(area_id,1,1)
WHEN 'c' THEN (SELECT country FROM country_id WHERE id=substr(area_id,2))
ELSE (SELECT province FROM province_id WHERE id=substr(area_id,2))
END AS name
FROM t_ad_area;
SELECT
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 60 THEN 'C'
ELSE 'D'
END AS grade
FROM exam_result;
SELECT
department,
SUM(CASE WHEN gender='M' THEN 1 ELSE 0 END) AS male_cnt,
SUM(CASE WHEN gender='F' THEN 1 ELSE 0 END) AS female_cnt,
COUNT(*) AS total
FROM employees
GROUP BY department;
IF()/CASE 在 SELECT 列表中為標量運算,開銷極低。CASE 可能阻礙索引使用,改寫為 OR/IN/UNION ALL。