Может использовать некоторые указатели для создания файла данных из SQL-запроса - PullRequest
0 голосов
/ 22 февраля 2012

Я мог бы использовать несколько указателей в моем запросе. У меня есть три внешние таблицы, которые мне нужно объединить и создать .dat-файл. Но мой запрос не очень эффективен и мог бы помочь с исправлением / улучшением этого. Он состоит из основной части, состоящей из двух частей: dc_item_loc_sourcing (1) и двух таблиц перевода dc_ccn190_sid_vtb (2) и dc_item_loc_vert_pim (3). Если комбинация item + loc не существует в 1 и 2, следует проверить 1 и 3.

SET heading OFF;    
SET feedback OFF; 
SET verify OFF; 
SET echo OFF;
SET linesize 1000;  
SET trimspool ON;
SET termout OFF;
SET newpage NONE;
SPOOL ../data/dc_sourcing.dat; 

SELECT DISTINCT TO_CHAR(item)
  || '|' ||store
  || '|' ||source_method
  || '|' ||primary_supp
  || '|' ||source_wh
  || '|' ||actie
  || '|' ||reward_eligible_ind
FROM ((SELECT dpac_tbl.item
      ,st.store
      ,dc_iloc.source_method
      ,dc_iloc.primary_supp
      ,dc_iloc.source_wh
      ,dc_iloc.actie
      ,dc_iloc.reward_eligible_ind
      ,MAX(dc_iloc.source_method) OVER (PARTITION BY dpac_tbl.item,st.store) max_src_pack
    FROM dc_item_loc_sourcing dc_iloc ,
      dc_ccn190_sid_vtb dpac_tbl ,
      store st ,
      item_master im ,
      item_loc il
    WHERE dc_iloc.dpac                         = dpac_tbl.dpac
    AND dpac_tbl.item                          = im.item
    AND CAST(dc_iloc.loc AS VARCHAR2(150byte)) = st.store_name_secondary
    AND st.store                               = il.loc
    AND dpac_tbl.item                          = il.item
    AND im.status                              = 'A'
    AND st.store_close_date                   >= SYSDATE
    AND il.status                              = 'A'
    AND dpac_tbl.ITEM NOT                     IN
      (SELECT IA.ITEM
      FROM ITEM_ATTRIBUTES IA
      WHERE IA.SH_STORE_ORDER_UNIT = 'N'
      AND IA.SH_TRADE_UNIT         = 'Y')
    UNION
    SELECT DISTINCT pi.item
      ,st.store
      ,dc_iloc.source_method
      ,dc_iloc.primary_supp
      ,dc_iloc.source_wh
      ,dc_iloc.actie
      ,dc_iloc.reward_eligible_ind
          ,MAX(dc_iloc.source_method) OVER (PARTITION BY pi.item,st.store) max_src_pack
    FROM dc_item_loc_sourcing dc_iloc ,
      dc_ccn190_sid_vtb dpac_tbl ,
      store st ,
      packitem pi ,
      item_master im ,
      item_loc il
    WHERE dc_iloc.dpac                         = dpac_tbl.dpac
    AND pi.pack_no                             = dpac_tbl.item
    AND pi.item                                = im.item
    AND CAST(dc_iloc.loc AS VARCHAR2(150byte)) = st.store_name_secondary
    AND il.item                                = pi.item
    AND il.loc                                 = st.store
    AND im.status                              = 'A'
    AND im.dept NOT                           IN (900,910,920,930)
    AND st.store_close_date                   >= SYSDATE
    AND il.status                              = 'A'
    AND PI.ITEM NOT                           IN
      (SELECT IA.ITEM
      FROM ITEM_ATTRIBUTES IA
      WHERE IA.SH_STORE_ORDER_UNIT = 'N'
      AND IA.SH_TRADE_UNIT         = 'Y'))
UNION
      (SELECT dpac_tbl.item ,
      st.store ,
      dc_iloc.source_method ,
      dc_iloc.primary_supp ,
      dc_iloc.source_wh ,
      dc_iloc.actie ,
      dc_iloc.reward_eligible_ind
      ,MAX(dc_iloc.source_method) OVER (PARTITION BY dpac_tbl.item,st.store) max_src_pack
    FROM dc_item_loc_sourcing dc_iloc ,
      dc_item_loc_vert_pim dpac_tbl ,
      store st ,
      item_master im ,
      item_loc il
    WHERE dc_iloc.dpac                          = dpac_tbl.dpac
    AND dpac_tbl.item                           = im.item
    AND CAST(dc_iloc.loc AS VARCHAR2(150 byte)) = st.store_name_secondary
    AND il.item                                 = dpac_tbl.item
    AND il.loc                                  = st.store
    AND im.status                               = 'A'
    AND dpac_tbl.artikel_type_lms NOT          IN ('V','S')
    AND st.store_close_date                    >= SYSDATE
    AND il.status                               = 'A'
    AND inventory_item_status_code             = 'Active'
    AND dpac_tbl.ITEM NOT                      IN
      (SELECT IA.ITEM
      FROM ITEM_ATTRIBUTES IA
      WHERE IA.SH_STORE_ORDER_UNIT = 'N'
      AND IA.SH_TRADE_UNIT         = 'Y')
    UNION
    SELECT DISTINCT pi.item ,
      st.store ,
      dc_iloc.source_method ,
      dc_iloc.primary_supp ,
      dc_iloc.source_wh ,
      dc_iloc.actie ,
      dc_iloc.reward_eligible_ind
          ,MAX(dc_iloc.source_method) OVER (PARTITION BY pi.item,st.store) max_src_pack

    FROM dc_item_loc_sourcing dc_iloc ,
      dc_item_loc_vert_pim dpac_tbl ,
      store st ,
      packitem pi ,
      item_master im ,
      item_loc il
    WHERE dc_iloc.dpac                          = dpac_tbl.dpac
    AND pi.pack_no                              = dpac_tbl.item
    AND pi.item                                 = im.item
    AND CAST(dc_iloc.loc AS VARCHAR2(150 byte)) = st.store_name_secondary
    AND il.item                                 = pi.item
    AND il.loc                                  = st.store
    AND im.status                               = 'A'
    AND dpac_tbl.artikel_type_lms NOT          IN ('V','S')
    AND im.dept NOT                            IN (900,910,920,930)
    AND st.store_close_date                    >= SYSDATE 
    AND il.status                               = 'A'
    AND inventory_item_status_code             = 'Active'
    AND pi.ITEM NOT                            IN
      (SELECT IA.ITEM
      FROM ITEM_ATTRIBUTES IA
      WHERE IA.SH_STORE_ORDER_UNIT = 'N'
      AND IA.SH_TRADE_UNIT         = 'Y'))) 
    WHERE source_method = max_src_pack;


SPOOL OFF;

1 Ответ

1 голос
/ 22 февраля 2012

Это не было проверено - в данный момент у меня нет экземпляра SQL, и, очевидно, у меня нет доступа к вашим таблицам. Я также не даю никаких гарантий относительно производительности, так как я не знаю о текущих показателях.

Ваша самая большая проблема, похоже, связана с использованием синтаксиса неявного соединения. Не используйте это, это анти-шаблон; это также учитывает некоторое «удивительное» поведение. Всегда явно указывайте свои объединения и ставьте (как можно больше) соответствующие условия в предложении ON - используйте предложение WHERE только при работе со ссылкой на таблицу в предложении FROM.

У меня также есть огромная проблема с этой строкой:
AND CAST(dc_iloc.loc AS VARCHAR2(150byte)) = st.store_name_secondary
Вы будете не (вероятно ... есть некоторые предостережения) использовать индекс для этого сравнения, который не поможет. С семантической точки зрения это также ужасная вещь - присоединяться - почему таблица местоположения элемента определяется (по-видимому) именем магазина? Это должно по ключу идентификатора магазина - который должен быть того же типа данных (без преобразований), и должен быть внутренним идентификатором, а не чем-то временным, как «имя».

WITH Excluded_Item (item) as (SELECT DISTINCT item
                              FROM Item_Attributes
                              WHERE sh_store_order_unit = 'N'
                              AND sh_trade_unit = 'Y'), -- These should be 1/0 flags
                                                        -- (char or numeric)
                                                        -- or boolean, if supported

SELECT CAST(item as CHAR) 
       || '|' || loc 
       || '|' || source_method 
       || '|' || primary_supp 
       || '|' || source_wh 
       || '|' || actie 
       || '|' || reward_eligible_ind 

FROM(SELECT DISTINCT c.item, c.loc,
                     a.source_method, a.primary_supp, a.source_wh, a.actie,
                     a.reward_eligible_ind,
                     MAX(a.source_method) 
                     OVER(PARTITION BY c.item, c.loc) as maxSourcePack
                                 -- this should be indexed
     FROM dc_item_loc_sourcing as a
     JOIN store as b
     ON b.store_name_secondary = CAST(a.loc as VARCHAR2(150 byte))
     AND b.store_close_date >= CURRENT_DATE
     JOIN item_loc as c
     ON c.loc = b.store
     AND c.status = 'A'
     JOIN item_master as d
     ON d.status = 'A'
     AND d.item = c.item
     LEFT JOIN Excluded_Item as e
     ON e.item = d.item
     LEFT JOIN dc_ccn190_sid_vtb as f
     ON f.dpac = a.dpac
     LEFT JOIN dc_item_loc_vert_pim as g
     ON g.dpac = a.dpac
     AND g.artikel_type_lms NOT IN ('V', 'S')
     AND inventory_item_status_code = 'Active' -- really?  And where is this from? 
     LEFT JOIN packitem as h
     ON (h.pack_no = f.item OR h.pack_no = g.item)
     AND h.item = d.item
     AND d.dept NOT IN (900, 910, 920, 930)
     WHERE e.item IS NULL
     AND (h.item IS NOT NULL
          OR (h.item IS NULL AND (f.item = d.item OR g.item = d.item))) ) as h

WHERE source_method = maxSourcepack

Я считаю это правильно, хотя определение ваших таблиц (и данных выборки) очень поможет в этом отношении - особенно в том, как определяется packitem.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...