需求:優先從 users 找用戶,找到即返回;找不到再去 users_archived 找。普通 UNION ALL 會掃描兩表並可能產生重複行。
SELECT id FROM users WHERE id = 123456
UNION ALL
SELECT id FROM users_archived WHERE id = 123456;
SELECT GREATEST(@found := -1, id) AS id, 'users' AS which_tbl
FROM users WHERE id = 1
UNION ALL
SELECT id, 'users_archived'
FROM users_archived WHERE id = 1 AND @found IS NULL
UNION ALL
SELECT 1, 'reset' FROM DUAL WHERE (@found := NULL) IS NOT NULL;
@found := -1 賦值為非 NULL,GREATEST(-1, id) 返回 id (正數)。若找到行,輸出該行,@found 變為 -1 (非 NULL)。WHERE ... AND @found IS NULL。若第一分支找到,@found 非 NULL,條件失效,**完全不掃描** users_archived。(@found := NULL) IS NOT NULL 永假 (NULL IS NOT NULL = FALSE),不產出行,**僅執行賦值重置** @found 為 NULL,不影響後續查詢。GREATEST(@var := val, col):在 SELECT 列表中完成「賦值 + 取值」原子操作,不輸出額外欄位@var IS NULL 作為守衛條件,實現短路DUAL 虛擬表配合永假條件完成變數重置,無副作用which_tbl 標識資料來源,方便應用層判斷