Обновление одного и того же столбца из разных столбцов другой таблицы

sql oracle11g

56 просмотра

3 ответа

Я использую следующие 3 запроса для обновления статуса на основе значения 3 разных столбцов из другой таблицы.

UPDATE NUMBER_TABLE  SET STATUS='X'  WHERE STATUS='P' AND NUMBER IN 
            (SELECT NVL(CONTACT_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P');

UPDATE NUMBER_TABLE  SET STATUS='X'  WHERE  STATUS='P' AND NUMBER IN 
            (SELECT NVL(HOME_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P');

UPDATE NUMBER_TABLE  SET STATUS='X'  WHERE  STATUS='P' AND NUMBER IN 
            (SELECT NVL(WORK_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P');

Все 3 запроса делают полное сканирование таблицы. Может кто-нибудь предложить лучший способ объединения 3 запросов в один

Автор: Ashish Источник Размещён: 08.11.2019 10:57

Ответы (3)


1 плюс

Решение

Нечто подобное должно работать.

ПРИМЕЧАНИЕ. Вы сказали, что используете эти три запроса для обновления ... Это не так. Ваши запросы не будут работать как написано; NUMBER - это зарезервированное ключевое слово Oracle, поэтому вы получите ошибки компиляции. Когда вы пишете, пожалуйста, будьте очень осторожны с тем, что вы говорите. Запрос, который я предлагаю ниже в качестве решения, также не будет работать по той же причине. Используйте ваши настоящие имена столбцов.

UPDATE NUMBER_TABLE n SET STATUS='X'  WHERE STATUS='P' AND EXISTS
   ( SELECT 1 FROM TMP_NUMBER_FOUND t where n.NUMBER = NVL(t.CONTACT_NO, 'XXXXXXXXXX')
                                      or    n.NUMBER = NVL(t.HOME_NO   , 'XXXXXXXXXX')
                                      or    n.NUMBER = NVL(t.WORK_NO   , 'XXXXXXXXXX')
   )
;

Добавлено на основе дополнительной информации от OP (см. Комментарии).

ОП поделился информацией о том, что 'XXXXXXXXXX'в его данных нет равных чисел . В этом случае он NVL(...)не нужен и только тратит время. Сравнение с 'XXXXXXXXXX'в этом случае будет таким же, как сравнение NULLс тем, что сравнение NULLникогда не вернется TRUE. Итак: удалите эти NVLобертки, они большой источник медлительности.

Это придет с другой, еще больше выгоды: колонны CONTACT_NO, HOME_NOи WORK_NOдолжно быть проиндексировано , если они не являются уже, и если они не окружены NVL(...), индексы фактически могут быть использованы. Там также должен быть указатель на NUMBER. ОП сказал, что этот столбец является частью PK, но не первым столбцом в PK, и спросил, должен ли он сделать его первым столбцом. Ответ ДА ​​- или, если есть веская причина, что другой столбец должен оставаться первым (возможно, другие запросы полагаются на это), тогда он NUMBERдолжен получить свой собственный индекс. Но если это можно сделать первым столбцом в ПК, этого должно быть достаточно.

Автор: mathguy Размещён: 20.08.2016 01:24

1 плюс

Вы можете использовать CASEс обновлением,

UPDATE NUMBER_TABLE  SET STATUS=(CASE when NUMBER IN 
            (SELECT NVL(CONTACT_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P') AND STATUS='P' then 'X'  
            when NUMBER IN 
            (SELECT NVL(HOME_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P') AND STATUS='P' then 'X'
              WHEN NUMBER IN  
            (SELECT NVL(WORK_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P') AND STATUS='P' then 'X' ELSE STATUS END);
Автор: Ashish Patil Размещён: 20.08.2016 02:01

0 плюса

Я предлагаю

UPDATE number_table n INNER JOIN tmp_number_found t
                              ON n.number = NVL(t.contact_no, 'XXXXXXXXXX')
                              OR n.number = NVL(t.home_no, 'XXXXXXXXXX')
                              OR n.number = NVL(t.work_no, 'XXXXXXXXXX')
   SET n.status='X'
 WHERE n.status='P'
   AND t.status='P'
;
Автор: Zach Victor Размещён: 20.08.2016 07:31
Вопросы из категории :
32x32