Oracle: обновить столбец в таблице a из значений в других таблицах - PullRequest
1 голос
/ 30 сентября 2010

Я пытаюсь поддерживать несколько баз данных для приложения, которое пишу.Приложение в основном использует Hibernate, но невероятно неэффективно перебирать миллионы строк и обрабатывать их по отдельности, когда оператор DML может обработать их за короткое время.Поэтому для определенных операций мне нужно отработать SQL.Я больше человек из MySQL, но у меня пока есть приложение, работающее с SQL Server и MySQL.Есть одна операция, которая поставила меня в тупик, и я просто не могу понять, как построить некоторые из запросов на обновление для Oracle.Я знаю, что это, вероятно, вопрос новичка в том, что касается Oracle, но я, должно быть, пропустил очевидные ответы, когда искал ....

Вот как я пишу этот тип запроса дляMySQL:

обновление table1 t1, table2 t2 set t1.colA = t2.colA, где t1.colB = t2.colB и t1.colC = t2.colC

MySQL имеет хорошую конструкцию, в которойВы можете просто указать все таблицы перед оператором 'set' с псевдонимами, что значительно упрощает остальную часть оператора.В SQL Server я использую update ... join, чтобы сделать то же самое.

В Oracle я пытался использовать 'update table1 set colA = (select ....) там, где существует (select....) синтаксис, но это не работает - он возвращает ошибку «подзапрос возвращает более одной строки».Я также пытался использовать слияние ... используя ... в синтаксисе, но это ошибки с "невозможно получить стабильный набор строк из исходных таблиц".

Чтобы более подробно объяснить, что я "Я пытаюсь достичь, у меня есть несколько запросов, некоторые из которых используют 2 таблицы, некоторые из них 3 таблицы.Самое сложное должно сделать это:

обновить tableA.colB со значением в tableC.colC, где tableA.colA = tableB.colA и tableB.colB = tableC.colB для всех совпадающих строк.В терминах данных это выглядит так (до и после):

Before:

Table A
-------
colA     colB
1        NULL
2        NULL
3        NULL
4        NULL

Table B
-------
colA     colB
1        A
2        A
3        B
4        B

Table C
-------
colB     colC
A        15
B        20

After:

Table A
-------
colA     colB
1        15
2        15
3        20
4        20

Надеюсь, это достаточно ясно.Может кто-нибудь объяснить, как написать этот вид DML-запроса для Oracle?Что касается бонусных баллов, будет ли это так же для PostgreSQL?:)

Ответы [ 3 ]

2 голосов
/ 30 сентября 2010

до

    SQL> select * from A
      2  /

          COLA       COLC
    ---------- ----------
             1
             2
             3
             4

    SQL> select * from B
      2  /

          COLA C
    ---------- -
             1 A
             2 A
             3 B
             4 B

    SQL> select * from C
      2  /

    C       COLC
    - ----------
    A         15
    B         20

    SQL>

Запрос

    SQL> update A
      2  set colc = ( select c.colc
      3               from c
      4                      join b on ( c.colB = b.colB )
      5               where
      6                  b.colA = A.colA )
      7  where exists
      8      ( select null
      9               from c
     10                      join b on ( c.colB = b.colB )
     11               where
     12                  b.colA = A.colA )
     13  /

    4 rows updated.

    SQL>

* После 1012 *

    SQL> select * from A
      2  /

          COLA       COLC
    ---------- ----------
             1         15
             2         15
             3         20
             4         20

    SQL>

Очевидно, что вы упростили что-то в своем тестовом примере, поэтому оно не соответствует вашей реальной ситуации. Главное, мой запрос работает, потому что подзапрос возвращает одну строку для каждого значения A.colA. Вам необходимо повторно посетить ваши данные и установить необходимые критерии. Это проблема данных / бизнес-логики, а не проблема синтаксиса.

2 голосов
/ 30 сентября 2010

Вы можете использовать distinct, чтобы игнорировать несколько копий одного и того же значения:

update  TableA
set     ColB = 
        (
        select  distinct ColC
        from    TableC C
        join    TableB B
        on      C.ColB = B.ColB
        where   B.ColA = TableA.ColA
        )

По-прежнему выдает ошибку, если найдено более одного подходящего значения.

0 голосов
/ 30 сентября 2010

Попробуйте следующее:

UPDATE table_a a
  SET col_b = (SELECT col_c
                 FROM table_b b,
                      table_c c
                 WHERE b.col_a = a.col_a AND
                       c.col_b = b.col_b);

У меня нет Postgresql на этой машине, поэтому я не могу это комментировать.

Поделитесь и наслаждайтесь.

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