2017-02-16 18 views
0

У меня есть таблица ACTIVITY_KEY со следующими полями:Обновление полой таблицы А, с использованием таблицы B столбцов, где таблица А имеет поле «_», отделенные и его соответствующие значения существуют в таблице B

COL1  COL2 COL3  COL4  COL5  COL6  COl7  
ACt1  A1_B1 
ACT2  C1 
ACT2  D1_D4 
ACT3  A1_F1 

полого COL3 в COL7 пустые

Теперь есть еще одна таблица KEYDEF с поля внизу и значение:

KEY  NAME  VAL 
A1  COL4   UI 
A1  COL6   2 
B1  COL3   98 
C1  COL5   N 
C1  COL4   00 
D1  COL3   1 
D1  COL4   PP 
D1  COL6   RT 
D4  COL5   Y   
D4  COL7   DG 
F1  COL7   NN 
F1  COL3   9T 

Я wnat обновить таблицу ACTIVITY_KEY для cOL3-COL7 со значениями из KEYDE F, и это должно быть следующим:

COL1  COL2 COL3  COL4  COL5  COL6  COL7 
ACt1  A1_B1 98  UI     2 
ACT2  C1    00   N 
ACT2  D1_D4  1  PP   Y  RT  DG 
ACT3  A1_F1 9T  UI     2  NN 

Я не уверен, как это сделать, может кто-то помочь?

+0

Пожалуйста, покажите нам, что вы пробовали до сих пор, и сказать нам, что у вас есть проблемы с ним. Почему 'col2' имеет несколько значений, разделенных таким образом? И может ли это иметь больше двух? –

+2

Если у вас была ситуация, когда 'ACTIVITY_KEY.COL2' был, скажем," D4_F1 ", что бы вы ожидали значения' COL7'? –

+0

Там не будет такой ситуации, как вы упомянули Мэтью, мы добавили это как ограничение. – Mishti

ответ

0

Вот очень простой подход. Предполагается, что у вас не будет ситуаций, когда ACTIVITY_KEY.COL2 является «D4_F1», например, так как это сделало бы значение COL7 неоднозначным.

select col1, col2, 
(SELECT val FROM keydef d 
    WHERE ak.col2 LIKE '%' || d.key || '%' 
    AND d.name = 'COL3' 
    AND ROWNUM = 1) col3, 
(SELECT val FROM keydef d 
    WHERE ak.col2 LIKE '%' || d.key || '%' 
    AND d.name = 'COL4' 
    AND ROWNUM = 1) col4, 
(SELECT val FROM keydef d 
    WHERE ak.col2 LIKE '%' || d.key || '%' 
    AND d.name = 'COL5' 
    AND ROWNUM = 1) col5, 
(SELECT val FROM keydef d 
    WHERE ak.col2 LIKE '%' || d.key || '%' 
    AND d.name = 'COL6' 
    AND ROWNUM = 1) col6, 
(SELECT val FROM keydef d 
    WHERE ak.col2 LIKE '%' || d.key || '%' 
    AND d.name = 'COL7' 
    AND ROWNUM = 1) col7 
from activity_key ak 

После того, как вы удовлетворены SELECT (выше), вы можете использовать его, чтобы фактически обновить столбцы, поместив его в MERGE заявление. Как:

MERGE TO ACTIVITY_KEY t 
USING (... SELECT statement above ...) u 
ON (t.col1 = u.col1 AND t.col2 = u.col2) -- assuming COL1+COL2 is unique... 
WHEN MATCHED THEN UPDATE... 
+0

Выбор запроса выглядит хорошо для меня, но как обновить? Как добавить туда имена полей полей? – Mishti

+0

@Matthhew: получение ошибки Отчет об ошибке - Ошибка SQL: ORA-30926: невозможно получить стабильный набор строк в исходных таблицах 30926. 00000 - «невозможно получить стабильный набор строк в исходных таблицах» * Причина: стабильный набор строк не может быть получен из-за большого dml действия или неопределенного предложения where. * Действие: Удалите любые недетерминированные предложения where и переиздайте dml. я добавил при температуре ниже: КОГДА MATCHEN ТОГДА ОБНОВЛЕНИЕ SET t.col3 = u.col3, t.col4 = u.col4, t.col5 = u.col5, t.col6 = u.col6, t.col7 = u.col7; – Mishti

+0

Я должен был видеть из ваших тестовых данных, что 'COL1' сам по себе не является уникальным.Можете ли вы совместить на 'COL1' и' COL2' вместе? Я обновил свой ответ, чтобы понять, что я имею в виду. –

1

Попробуйте это слияние:

merge into ACTIVITY_KEY a 
using (
    select 
     a.col1, 
     a.col2, 
     max(k.col3) col3, 
     max(k.col4) col4, 
     max(k.col5) col5, 
     max(k.col6) col6, 
     max(k.col7) col7 
    from ACTIVITY_KEY a 
    left join (
     select * 
     from keydef 
     pivot (
      max(val) for name in (
       'COL3' as col3, 
       'COL4' as col4, 
       'COL5' as col5, 
       'COL6' as col6, 
       'COL7' as col7 
      ) 
     ) 
    ) k on a.col2 like '%'||k.key||'%' 
    group by a.col1, a.col2 
) k on (
    a.col1 = k.col1 
    and a.col2 = k.col2 
) 
when matched then update set 
    a.col3 = k.col3, 
    a.col4 = k.col4, 
    a.col5 = k.col5, 
    a.col6 = k.col6, 
    a.col7 = k.col7; 

Как @Matthew отметил в комментариях, если вы можете иметь столкновения. вышеприведенное решение будет принимать максимальное значение.

+0

@ gurV- я попробовал то, что вы предложили, но получаю ошибку для этого: Сообщение об ошибке - Ошибка SQL: ORA-00905: отсутствует ключевое слово 00905. 00000 - "отсутствует ключевое слово" * Причина: * Действие: – Mishti

+0

отсутствует "then" .. Обновлено. попробуйте сейчас – GurV

0

Просто другой подход. Надеюсь, поможет.

MERGE INTO ACTIVITY_KEY C USING 
(SELECT col1, 
    COL2, 
    MAX(COL3) COL3, 
    MAX(COL4) COL4, 
    MAX(COL5) COL5, 
    MAX(COL6) COL6, 
    MAX(col7) col7 
FROM 
    (SELECT B.COL1, 
    B.COL2, 
    CASE 
     WHEN A.name = 'COL3' 
     THEN A.VAL 
    END COL3, 
    CASE 
     WHEN A.name = 'COL4' 
     THEN A.VAL 
    END COL4, 
    CASE 
     WHEN A.name = 'COL5' 
     THEN A.VAL 
    END COL5, 
    CASE 
     WHEN A.name = 'COL6' 
     THEN A.VAL 
    END COL6, 
    CASE 
     WHEN A.name = 'COL7' 
     THEN A.VAL 
    END COL7 
    FROM KEYDEFF a, 
    activity_key B 
    WHERE (a.key=SUBSTR(B.COL2,1,2) 
    OR a.key =SUBSTR(B.COL2,LENGTH(b.col2)-1,LENGTH(b.col2))) 
) 
GROUP BY COL1, 
    COL2 
)B ON (B.COL1 = C.COL1 AND B.COL2 = C.COL2) 
WHEN matched THEN 
    UPDATE 
    SET COL3 = B.COL3, 
    COL4 = B.COL4, 
    COL5 = B.COL5, 
    COL6 = B.COL6, 
    col7 = b.col7; 
0

Это очень простой запрос для получения результата.

enter image description here ----------

+0

введите код прямо, вместо того чтобы помещать его в качестве изображения и иметь его ссылку здесь. –

 Смежные вопросы

  • Нет связанных вопросов^_^