如何替换Oracle SQL 查询中的OR 条件?

How to replace the OR condition in the Oracle SQL query?

我正在使用 Oracle Database 12c 企业版 12.2.0.1.0 版 - 64 位生产

有人可以告诉我如何重写下面的游标查询,以便

它没有在 where 条件中使用“OR”子句

性能优势。

基本上应该在查询中适当删除 OR 条件。

CURSOR c_picklist_dtl IS
SELECT DISTINCT pd.dc_code,
               pd.storer,
               pd.picklist_key,
               pd.pickdetail_key,
               pd.line_no,
               pd.pick_type,
               pd.case_id,
               pd.order_type,
               pd.sub_type,
               pd.order_no,
               pd.item,
               pd.consignee,
               pd.bin_code,
               pd.lot,
               pd.pallet_id,
               pd.packkey,
               pd.to_pick_qty,
               am.bin_code dispatch_bin_code,
               ph.wave_id,
               ph.po_no,
               pd.pick_area_type,
               pd.assignment_id,
               pd.pick_method,
               pd.pack_method,
               pd.ord_priority,
               pd.pick_seq_no 

 FROM table1 ph,
      table2 pd,
      table3 ot,
      table4 am
WHERE    pd.dc_code = ph.dc_code
      AND pd.storer = ph.storer
      AND pd.picklist_key = ph.picklist_key
      AND ph.dc_code = p_dc_code
      AND ph.storer = p_storer
        AND (  (   ph.po_no = p_order_no
               AND p_order_prefix = 'X'
               AND pd.pick_method = 'P'
               AND pd.status = 'E' 
                                   )
           OR (   ph.wave_id = p_order_no
               AND p_order_prefix = 'W'
               AND pd.pick_method = 'P'
               AND pd.status = 'E' 
                                   ) 

          )
      AND pd.item = p_item
      AND pd.consignee = p_consignee
      AND pd.dc_code = ot.dc_code
      AND pd.order_type = ot.order_type
      AND pd.sub_type = ot.sub_type
      AND am.dc_code(+) = ot.dc_code
      AND am.dc_area(+) = ot.dispatch_area
      AND pd.to_pick_qty > 0
  ORDER BY pd.dc_code,
      pd.item,
      pd.consignee,
      pd.pick_seq_no,
      pd.pickdetail_key,
      pd.line_no;


Thanks           

您可以避免重复相同的 2 个测试。
要走得更远,您需要了解应用程序并理解逻辑。

        AND (  (   ph.po_no = p_order_no
               AND p_order_prefix = 'X' 
            OR                       )
                (   ph.wave_id = p_order_no
               AND p_order_prefix = 'W')  )   
         AND pd.pick_method = 'P'
         AND pd.status = 'E' 

可以替代

        AND (  (   ph.po_no = p_order_no
               AND p_order_prefix = 'X'
               AND pd.pick_method = 'P'
               AND pd.status = 'E' 
                                   )
           OR (   ph.wave_id = p_order_no
               AND p_order_prefix = 'W'
               AND pd.pick_method = 'P'
               AND pd.status = 'E' 
                                   ) 

          )

你的 OR 子句除了一个输入参数的一个文字比较和不同的匹配列之外几乎相同,这几乎意味着你可以替换:

   AND (  (   ph.po_no = p_order_no
           AND p_order_prefix = 'X'
           AND pd.pick_method = 'P'
           AND pd.status = 'E' 
                               )
       OR (   ph.wave_id = p_order_no
           AND p_order_prefix = 'W'
           AND pd.pick_method = 'P'
           AND pd.status = 'E' 
                               ) 

      )

就像这样:

AND p_order_no = CASE WHEN p_order_prefix = 'X' THEN ph.po_no
                      WHEN p_order_prefix = 'W' THEN ph.wave_id
                      ELSE NULL
                 END
AND pd.pick_method = 'P'
AND pd.status      = 'E'