2016-05-04 228 views
0

我試圖重寫一些看起來特別糟糕的舊SQL查詢。我想知道是否有一種更有效的方法來優先排序where語句中的值的優先順序。基本上這個表格包含了每個用戶的多個email_code記錄,但是我想根據哪些記錄是首選的優先順序。在這種情況下,如果email_code是WORK,它應該被選中。但是,如果沒有工作記錄,則應選擇HOME,依此類推。這是我正在使用的一個例子。必須有一個更優雅的方式來做到這一點......?基於優先級的oracle select

select 
    * 
from 
    email m 
where 
    status_ind='A' 
    and decode(email_code, 'WORK',1, 
          'HOME',2, 
          'ALT1',3, 
          'ALT2',4,5) = (select 
              min(decode(email_code, 'WORK',1, 
                   'HOME',2, 
                   'ALT1',3, 
                   'ALT2',4,5)) 
             from 
              email 
             where 
              email_uid = m.email_uid 
              and status_ind='A'); 
+0

你指的是COALESCE嗎? https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions023.htm – Danilo

+0

我不認爲COALESCE在這種情況下工作。在某些情況下,記錄可能包含全部4個這樣的代碼。它更多關於優先順序。 – oljones

回答

1

嘗試:

SELECT * FROM (
    SELECT e.*, 
      dense_rank() over (PARTITION BY user_id 
      ORDER BY CASE email_code 
       WHEN 'WORK' THEN 1 
       WHEN 'HOME' THEN 2 
       WHEN 'ALT1' THEN 3 
       WHEN 'ALT2' THEN 4 
       ELSE 5 
      END) As priority 
    FROM emails e 
    WHERE status_ind='A' 
) 
WHERE priority = 1 
+0

這對我的情況最有效。謝謝! – oljones

0

唉我沒有甲骨文在這裏,但我認爲你可以使用這樣的事情

select * from (
    select *,min(decode(email_code, 'WORK',1, 
     'HOME',2,'ALT1',3,'ALT2',4,5)) mincode 
     over(partition by (email_uid)) 
    where status_ind='A' 
) where email_code=mincode 
0

首先,它應是最好創建一個查詢表來保存電子郵件類型及其優先級。然後,您可以將此查找表與您的郵件表一起加入。最後,可以使用Oracle分析函數(row_number,rank,dense_rank等)來獲得最高優先級的分析函數。