Oracle SQL Query根据优先级将值分配到不同的行

时间:2014-11-16 11:00:04

标签: sql oracle

我想编写SQL查询,根据优先级将值分配或添加到不同的行中。

这是我的情景。

我有一个名为M_FLIGHT的表,其中包含以下数据。

DEPARTURE_DATE  FLIGHT_NO  FAIR_TYPE          PRIORITY  AVAILABLE_SEATS  MAX_CAPACITY  RETURN_SEAT
==============  =========  =================  ========  ===============  ============  ===========
05-DEC-14       SC-917     Normal Fair           1         7                10             4
05-DEC-14       SC-917     Maharaja Standard     2         8                10             0
05-DEC-14       SC-917     Maharaja Special      3         9                10             0

航班可以有不同的公平类型(即师范博览会,大君标准,大君德里特别等),优先级分别为1,2和3。

如果用户取消/返回预订的座位,则我需要将RETURN_SEAT值添加到AVAILABLE_SEATS值,使其不超过该展会类型的MAX_CAPACITY值。

如果超过,则将剩余价值添加到下一个优先级(即下一个公平类型)。

因此,最终结果应如下所示

DEPARTURE_DATE  FLIGHT_NO  FAIR_TYPE          PRIORITY  AVAILABLE_SEATS  MAX_CAPACITY  RETURN_SEAT
==============  =========  =================  ========  ===============  ============  ===========
05-DEC-14       SC-917     Normal Fair           1         10               10             4
05-DEC-14       SC-917     Maharaja Standard     2         9                10             0
05-DEC-14       SC-917     Maharaja Special      3         9                10             0

2 个答案:

答案 0 :(得分:3)

您可以使用累计总和计算占用的空间:

select f.*, sum(max_capacity-available_seats) as occupied,
        sum(max_capacity-available_seats) over (order by priority) as cumeocc
from m_flight f;

有了这些信息,您可以分配v_Num个新席位:

select f.*,
       (case when v_Num >= cumeocc - occupied
             then greatest(v_num - (cumeocc - occupied), occupied)
             else occupied
        end) as new_occupied
from (select f.*, (max_capacity-available_seats) as occupied,
              sum(max_capacity-available_seats) over (order by priority) as cumeocc
      from m_flight f
     ) f;

然后下一步是将这些信息合并。这有点难以表达,因为你在每一行上都没有明显的键。我建议你在表格中添加一个单列主键。

答案 1 :(得分:0)

我为这项业务写了一个更新查询。

update M_FLIGHT d
   set d.AVAILABLE_SEATS =
       (select case
                 when (f.available_seats + Case
                        when ((select sum(s.return_seat) from M_FLIGHT s) -
                             nvl((select sum(s.max_capacity - s.available_seats)
                                    from M_FLIGHT s
                                   where s.priority < f.priority),
                                  0)) > 0 THEN
                         ((select sum(s.return_seat) from M_FLIGHT s) -
                         nvl((select sum(s.max_capacity - s.available_seats)
                                from M_FLIGHT s
                               where s.priority < f.priority),
                              0))
                        Else
                         0
                      END) >= f.max_capacity then
                  f.max_capacity
                 else
                  (f.available_seats + Case
                    when ((select sum(s.return_seat) from M_FLIGHT s) -
                         nvl((select sum(s.max_capacity - s.available_seats)
                                from M_FLIGHT s
                               where s.priority < f.priority),
                              0)) > 0 THEN
                     ((select sum(s.return_seat) from M_FLIGHT s) -
                     nvl((select sum(s.max_capacity - s.available_seats)
                            from M_FLIGHT s
                           where s.priority < f.priority),
                          0))
                    Else
                     0
                  END)
               end as avail_new
          from M_FLIGHT f
         where f.priority = d.priority);

我知道很难阅读这个查询,但它确实有用。也许您需要为子查询添加一些过滤器(例如DEPARTURE_DATE,FLIGHT_NO,...)。

感谢您提出一些需要思考的问题。我喜欢它。