Обновить столбец таблицы в зависимости от состояния существующей и другой таблицы - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть две огромные таблицы с миллионами re c, ORDER и ORDER_DETAILS

    ORDER
    id NUMBER;
    desc VARCHAR;
    code VARCHAR;
    total_amount NUMBER;

    ORDER_DETAILS    
    id NUMBER;
    desc VARCHAR;
    code VARCHAR;
    amount NUMBER;

    ORDER table contains 'total amount' per id, desc
    ORDER 
    ID DESC CODE, TOTAL_AMOUNT
    1  tl1  OTL1  20
    2  tl2  OTL8  50

ORDER_DETAILS содержит половину общего количества (количество) в заказе (id & des c)

ORDER_DETAILS 
    ID DESC CODE, AMOUNT
    1  tl1  NULL  10
    1  tl1  NULL  10
    2  tl2  NULL  10
    2  tl2  NULL  10
    2  tl2  NULL  20
    2  tl2  NULL  10

Мне нужно обновить order_detail.code, используя алгоритм:

 IF SUM(AMOUNT) = TOTAL_AMOUNT -per id & desc
 THEN UPDATE SET order_detail.code=ORDER.CODE

Итак, результаты должны быть такими:

ORDER_DETAILS 
 ID DESC CODE, AMOUNT
 1  tl1  OTL1  10
 1  tl1  OTL1  10
 2  tl2  OTL8  10
 2  tl2  OTL8  10
 2  tl2  OTL8  20
 2  tl2  OTL8  10

Я пробовал следующее, но это никогда не заканчивается:

    UPDATE ORDER_DETAIL A SET A.CODE = (SELECT TEMP1.CODE
                                         FROM                        
                                        ( SELECT 
                                           ID, 
                                           CODE,
                                           DESC,
                                           TOTAL_AMOUNT,
                                           SUM (AMOUNT) SUMAMNT
                                          FROM ORDER A, ORDER_DETAIL B
                                          WHERE A.ID  = B.ID
                                          AND   A.DESC  = B.DESC    
                                          AND   B.AMOUNT<>0
                                          AND   B.CODE IS NULL 
                                          GROUP BY AMOUNT ,ID, CODE, DESC, TOTAL_AMOUNT 
                                          HAVING SUM (AMOUNT) = A.TOTAL_AMOUNT) TEMP1
                                          WHERE A.ID=TEMP1.ID
                                          AND   A.DESC=TEMP1.DESC
                                        );

Как мне достичь желаемого результата? Если возможно, используя одно заявление sql?
Любая помощь приветствуется и благодарит вас заранее

Привет, Теджа sh, Спасибо за ваш ответ Пожалуйста, проверьте план ниже, стоимость огромна, он выполняет полное сканирование обеих таблиц - дважды @ ORDER_DETAILS

Plan

MERGE STATEMENT  CHOOSE
Cost: 2.894.308                                     
    13 MERGE ORDER_DETAILS                              
        12 VIEW                             
            11 HASH JOIN  Cost: 2.894.308  Bytes: 246,708  Cardinality: 1,068                       
                8 VIEW  Cost: 2.375.331  Bytes: 115,344  Cardinality: 1,068                     
                    7 FILTER                
                        6 SORT GROUP BY  Cost: 2.375.331  Bytes: 76,896  Cardinality: 1,068             
                            5 HASH JOIN  Cost: 2.367.824  Bytes: 3.834.697.392  Cardinality: 53.259.686         
                                2 PARTITION RANGE ALL  Cost: 517,16  Bytes: 1.757.569.638  Cardinality: 53.259.686  
                                    1 TABLE ACCESS FULL TABLE ORDER_DETAILS Cost: 517,16  Bytes: 1.757.569.638  Cardinality: 53.259.686  
                                4 PARTITION RANGE ALL  Cost: 1.512.742  Bytes: 3.576.967.836  Cardinality: 91.717.124  
                                    3 TABLE ACCESS FULL TABLE ORDER Cost: 1.512.742  Bytes: 3.576.967.836  Cardinality: 91.717.124  
                10 PARTITION RANGE ALL  Cost: 518,328  Bytes: 6.550.941.378  Cardinality: 53.259.686    
                    9 TABLE ACCESS FULL TABLE ORDER_DETAILS Cost: 518,328  Bytes: 6.550.941.378  Cardinality: 53.259.686 

Ответы [ 2 ]

0 голосов
/ 20 февраля 2020

Вы можете использовать оператор MERGE следующим образом (это будет быстрее, чем ваш оператор UPDATE):

MERGE INTO ORDER_DETAILS TRG 
USING 
(
   SELECT
       O.ID, O.DESC, O.CODE, 
       SUM(OD.AMOUNT),
       O.TOTAL_AMOUNT
   FROM
       ORDER_DETAILS OD
       JOIN "ORDER" O ON O.ID = OD.ID AND O.DESC = OD.DESC
   GROUP BY O.ID, O.DESC, O.CODE, O.TOTAL_AMOUNT
   HAVING O.TOTAL_AMOUNT = SUM(OD.AMOUNT)
)
SRC ON ( SRC.ID = TRG.ID AND SRC.DESC = TRG.DESC )
WHEN MATCHED THEN 
UPDATE SET TRG.CODE = SRC.CODE;

Cheers !!

0 голосов
/ 20 февраля 2020

Я знаком только с ms SQL, но я думаю, что следующее стандартно SQL и применимо к большинству БД.

Begin tran
 Update t 
      Set t.code = t.hdr
  From(
     Select d.code, o.code as her
       From order_detail d
        Join order o on o.id = d.id) t
Commit tran
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...