2015-10-29 2 views
0

Допустим, у вас есть таблицы:Условное обновление таблицы SQL с РЕГИСТРИРУЙТЕСЬ

CREATE TABLE TABLE1 (ID INTEGER PRIMARY KEY, VAL INT, CONDITION INT); 
CREATE TABLE TABLE2 (ID INTEGER PRIMARY KEY, VAL INT, CONDITION INT); 

с данными:

INSERT INTO TABLE1 VALUES (0, 0, 100); 

и

INSERT INTO TABLE2 VALUES 
(0, 2, 100), 
(1, 1, 100), 
(3, 3, 100) 

Что будет в TABLE1 после этого запроса и почему ?

UPDATE TABLE1 SET VAL = SOURCE.VAL 
FROM TABLE2 SOURCE 
WHERE TABLE1.CONDITION = SOURCE.CONDITION 

я получил:

0;2;100 

Означает ли это, что СУБД выполняется UPDATE операцию несколько раз, и я вижу только конечный результат? Или он обновляет VAL только один раз?

Объясните:

"Update on table1 (cost=270.68..562.65 rows=18818 width=24)" 
" -> Merge Join (cost=270.68..562.65 rows=18818 width=24)" 
"  Merge Cond: (table1.condition = source.condition)" 
"  -> Sort (cost=135.34..140.19 rows=1940 width=14)" 
"    Sort Key: table1.condition" 
"    -> Seq Scan on table1 (cost=0.00..29.40 rows=1940 width=14)" 
"  -> Sort (cost=135.34..140.19 rows=1940 width=14)" 
"    Sort Key: source.condition" 
"    -> Seq Scan on table2 source (cost=0.00..29.40 rows=1940 width=14)" 

Я использовал PostgreSQL.

+0

Попробуйте установить VAL = SOURCE.VAL + 100 – jarlh

+0

@jarlh, получил '0; 102; 100'. Но как RDBMS выбирает, какую строку из 'TABLE2' использовать? Получает ли он первую строку и пропускает другие? – pbespechnyi

ответ

2

Из documentation:

целевая строка не должен присоединиться к более чем одной строки из другой таблицы (ов). Если это так, то только одна из строк соединения будет использоваться для обновления целевой строки, но какая из них будет использоваться, не является легко предсказуемой.

Таким образом, поведение, которое вы видите, является именно тем, что должно произойти.

1

Ваш вопрос, похоже, о том, что происходит, когда в обновляемых таблицах имеется несколько совпадений. На выход выводится только одно значение. Для обновления используется произвольная совпадающая строка.

documentation объясняет, что происходит:

Примечание

Когда ЕК присутствует, то, по существу, происходит то, что целевой таблица присоединилась к таблицам, упомянутым в from_list, и каждая выходная строка соединения представляет собой операцию обновления для целевой таблицы . При использовании FROM вы должны убедиться, что соединение производит не более одной выходной строки для каждой строки, подлежащей изменению. Другими словами, целевая строка не должна соединяться более чем с одной строкой от другой таблицы (0) . Если это так, то только одна из строк соединения будет использоваться для обновить целевую строку, но какая из них будет использоваться, не легко предсказуема.

Из-за этой неопределенности ссылка на другие таблицы только в пределах подвыборки более безопасна, хотя часто сложнее читать и медленнее, чем с использованием соединения.

0

Это зависит от цели. В этом случае в случае таблиц он выберет одно совпадение записи (в первую очередь первое) и будет использовать это. Вы можете проверить это, создав триггер в таблице1 и отметьте, сколько раз запись была изменена. Если целью была не таблица, а переменная, то обновление будет происходить за каждую строку. Это быстрый способ конкатенации значений, например.