首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Oracle DECODE 函數多條件排序改用 CASE WHEN 實作

     編輯:程式設計疑難解答

問題現象

需求:依 de.status 排序,但當 status=2 且 結束時間 - 開始時間 > 0 時,需調整排序優先級。DECODE 單一值比較,無法直接處理複合條件。

DECODE 限制

-- DECODE 只能做單值等值比較
ORDER BY DECODE(de.status, 2, 1, 3, 2, 1, 3, 4, 4)
-- 無法加入:AND (de.end_time - de.start_time) > 0

解決方案:CASE WHEN 多條件排序

ORDER BY 
    CASE 
        WHEN de.status = 2 AND (de.end_time - de.start_time) > 0 THEN 1  -- 最高優先
        WHEN de.status = 2 THEN 2
        WHEN de.status = 3 THEN 3
        WHEN de.status = 1 THEN 4
        WHEN de.status = 4 THEN 5
        ELSE 99
    END,
    de.start_time  -- 次要排序:開始時間

完整查詢範例

SELECT de.*
FROM delivery de
ORDER BY 
    CASE 
        WHEN de.status = 2 AND (de.end_time - de.start_time) > 0 THEN 1
        WHEN de.status = 2 THEN 2
        WHEN de.status = 3 THEN 3
        WHEN de.status = 1 THEN 4
        WHEN de.status = 4 THEN 5
        ELSE 99
    END,
    de.created_at DESC;

CASE WHEN vs DECODE 對比

特性DECODECASE WHEN
語法標準Oracle 專有ANSI SQL 標準 (跨資料庫)
比較類型僅等值比較支援任意布林表達式 (<, >, BETWEEN, LIKE, AND/OR)
多條件不支援 (需嵌套)原生支援
可讀性簡單情況較簡潔複雜邏輯結構清晰
效能相同 (優化器同等對待)相同

進階:動態排序欄位

ORDER BY 
    CASE :sort_by
        WHEN 'status_priority' THEN 
            CASE 
                WHEN de.status = 2 AND (de.end_time - de.start_time) > 0 THEN 1
                WHEN de.status = 2 THEN 2
                ELSE 99
            END
        WHEN 'created_desc' THEN de.created_at
        WHEN 'amount_asc' THEN de.amount
        ELSE de.id
    END DESC;

常見錯誤

錯誤修正
CASE 回傳資料型別不一致所有 THEN/ELSE 回傳相同型別 (數字/字串/日期)
忘記 END每個 CASE 必須以 END 結束
NULL 值排序異常加入 NULLS FIRST/LAST 或 NVL(col, 默認值)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved