Обновить столбец значениями из другого столбца - PullRequest
1 голос
/ 26 августа 2009

У меня есть такая таблица:

create table foo ( a number, b number ) 

Я хочу обновить все столбцы из a со значением, которое находится в другой таблице

create table bar ( x number, y number ) 

Итак, если бы это был процедурный язык программирования, я бы:

 foreach foo_item in foo 
     foreach bar_item in bar 
         if( foo_item.b == bar_item.y ) 
             foo_item.a = bar_item.x 
         end
     end
 end

Я пытался

update foo 
set a = ( select distinct( x ) from bar where bar.y = foo.b ) 

Но зависает .... Я не совсем уверен, как сделать такую ​​вещь (или даже что гуглить)

Спасибо

РЕДАКТИРОВАТЬ Извините, мой плохой. Он не зависает, но пытается установить нулевое значение, и у меня есть ограничение (которое я не могу удалить)

Спасибо за помощь до сих пор

Ответы [ 6 ]

3 голосов
/ 26 августа 2009

Существует две возможные причины для обновления попытки перейти с foo.a на NULL.

  1. В foo есть строки, для которых в строке нет совпадающих строк.
  2. Соответствующая строка в баре имеет значение bar.x, равное нулю.

Следующее исключит обновления для foo, если выполняется любое из указанных выше условий. В этих случаях foo.a останется таким, каким он был:

update foo 
set a = (select distinct( x ) from bar where bar.y = foo.b )
where exists 
  (select *
  from bar 
  where bar.y = foo.b
  and bar.x is not null);
2 голосов
/ 26 августа 2009

Это не удается / вращается:

UPDATE foo 
   SET b = (SELECT DISTINCT(x) 
              FROM bar 
             WHERE bar.y = foo.b)

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

1 голос
/ 26 августа 2009

Предположим, у вас есть следующие значения.

foo(a,b) = [{0,2}]
bar(x,y) = [{1,2},{2,2},{3,2}]

Ответ, приведенный выше, вызывает ошибку ORA-01427. К заявлению нужны некоторые дополнения, которые зависят от ожидаемого результата.
Если вы ожидаете, что наибольший столбец (x, 2) должен храниться в foo (a, 2).

foo(a,b) = [{3,2}]
update foo 
  set a = (select max(x) from bar where bar.y = foo.b  
           and bar.x is not null)
where exists 
  (select *
  from bar 
  where bar.y = foo.b
  and bar.x is not null);

Если вы ожидаете какое-либо значение бара (x, 2), напишите следующее.

foo(a,b) = [{[1|2|3],2}]
update foo 
  set a = (select x from bar where bar.y = foo.b 
           and bar.x is not null 
           and rownum < 2)
where exists 
  (select *
  from bar 
  where bar.y = foo.b
  and bar.x is not null);

Порядок подвыбора зависит от хранения и извлечения строки. Оба обновления могут дать одинаковый результат. Без ORDER BY порядок строк не предсказуем. rownum <2 </strong> занимает только первый ряд подвыбора.

1 голос
/ 26 августа 2009

В указанном вами запросе вы обнаружите опечатку. В своем процедурном коде вы изменяете значение foo.a, но ваш запрос обновляет foo.b:

update foo set a = ( select distinct( x ) from bar where bar.y = foo.b )

Также, если есть много строк с одинаковыми значениями для bar.y, могут возникнуть проблемы. Ваш подзапрос может вернуть набор результатов, а не одно значение, ожидаемое вашим назначением. Например, если ваши данные

foo(x,y) = [{1,2},{2,2},{3,2}]

Тогда "DISTINCT x" вернет '{1,2,3}'

1 голос
/ 26 августа 2009

обновить набор boo (выбрать различное ( х) из бара, где bar.y = foo.b)

Может зависнуть по соображениям производительности, но должно работать. Дважды проверьте, что происходит, если нет bar.y, равного foo.b. Если это устанавливает b в нуль, хорошо?

0 голосов
/ 26 августа 2009

Если вы используете MS SQL Server или Sybase, вы можете использовать следующее,

обновить foo set b = x из бара, где bar.y = foo.b

Извините, я не видел, что вы используете Oracle. Я полагаю, вам нужно создать хранимую процедуру для этого.

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