根据oracle存在的行数选择单行

时间:2016-03-26 12:07:40

标签: sql oracle conditional

我使用查询得到了下表,现在我想根据下面解释的条件获取单个记录,并将其分配给我的存储过程中声明的两个变量,即v_dte_meetingv_status_meeting,< / p>

 Dte_Meeting| Ststus_Meeting
########################
15-Oct-14   | Due    
30-Oct-14   | Due
15-Dec-14   | Init
30-Dec-14   | Init
30-Nov-15   | Approved

我想根据以下条件为这些变量赋值:

  1. 如果Status_Meeting中显示的单个或多个记录为“截止日期”,请将v_dte_meeting指定为“截止日期”状态的最大日期,并为值为“截止日期”的v_status_meeting分配
  2. 如果上述条件失败,请检查Ststus_Meeting中存在的单个或多个记录为“Init”如果是,则将v_dte_meeting指定为“Init”状态的最大日期,并为值为“Init”的v_status_meeting分配
  3. 如果两个条件都失败,则分配两个变量NULL值
  4. 请帮我在Oracle中以最佳方式进行操作

2 个答案:

答案 0 :(得分:0)

一种方法使用聚合:

?- problem(Sudoku),constraint(Sudoku),search_pause(Sudoku,BT),print(Sudoku,BT).
    [[1,3,6,2,_,_,7,4,_],
     [_,2,5,_,1,_,_,_,_],
     [4,8,_,_,6,_,_,5,_],
     [_,_,_,7,8,_,2,1,_],
     [5,_,_,_,9,_,3,7,_],
     [9,_,_,_,3,_,_,_,5],
     [_,4,_,_,_,6,8,9,_],
     [_,5,3,_,_,1,4,_,_],
     [6,_,_,_,_,_,_,_,_]]
     Board[1,3] = 6
     Backtracks = 1

   more ;

但是,我认为更简单的版本只使用select (case when sum(case when status_meeting = 'Due' then 1 else 0 end) > 0 then max(case when status_meeting = 'Due' dte_meeting end) when sum(case when status_meeting = 'Init' then 1 else 0 end) > 0 then max(case when status_meeting = 'Init' then dte_meeting end) end), (case when sum(case when status_meeting = 'Due' then 1 else 0 end) > 0 then'Due' when sum(case when status_meeting = 'Init' then 1 else 0 end) > 0 then 'Init' end) into v_dte_meeting, v_status_meeting from t;

order by

select max(dte_meeting), max(status_meeting) into v_dte_meeting, v_status_meeting from (select t.* from t where status_meeting in ('Due', 'Init') order by (case when status_meeting = 'Due' then 1 when status_meeting = 'Init' then 2 end) ) t where rownum = 1; 只是为了确保返回一行。

答案 1 :(得分:0)

希望这会有所帮助。我只显示SELECT语句(我没有创建变量,所以我没有选择INTO,但这不是你的难度,你知道怎么做。)我使用子查询因子(WITH子句) ),仅在版本&gt; = 11中可用,我相信,否则您可以重写以将子查询放在它们所属的位置。

注意使用rank();在戈登的解决方案中,他会在所有行中获取max(dte),而不仅仅是那些状态=&#39; Due&#39;,因此它不能像他所写的一样简单。编辑:我也没有看到他选择NULL的位置,如果没有,那么就是NULL。也不是&#39; Init&#39;存在。 (对不起,这应该是对他的回答的评论,我缺乏特权。)

WITH t (Date_Meeting, Status_Meeting) AS
   (
      SELECT TO_DATE('15-OCT-14', 'DD-MON-YY'), 'Due' FROM dual UNION ALL
      SELECT TO_DATE('30-OCT-14', 'DD-MON-YY'), 'Due' FROM dual UNION ALL
      SELECT TO_DATE('15-DEC-14', 'DD-MON-YY'), 'Init' FROM dual UNION ALL
      SELECT TO_DATE('30-DEC-14', 'DD-MON-YY'), 'Init' FROM dual UNION ALL
      SELECT TO_DATE('15-NOV-15', 'DD-MON-YY'), 'Approved' FROM dual
   ),
     s (Date_Meeting, Status_Meeting) AS
   (
      SELECT Date_Meeting, Status_Meeting FROM t 
            WHERE Status_Meeting = 'Due' OR Status_Meeting = 'Init'
      UNION ALL SELECT NULL, NULL FROM dual  -- To ensure you have the nulls if needed
   ),
    r (Date_Meeting, Status_Meeting, rk) AS
   (
      SELECT Date_Meeting, Status_Meeting, 
             RANK() OVER (ORDER BY DECODE(Status_Meeting, 'Due', 0, 'Init', 1, 2), 
                          Date_Meeting DESC)  -- make sure you understand this
      FROM s
   )
SELECT Date_Meeting, Status_Meeting FROM r WHERE rk = 1
/

结果:

DATE_MEET STATUS_M
--------- --------
30-OCT-14 Due

1 row selected.