2016-05-04 230 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等)来获得最高优先级的分析函数。