Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.08.27;
Скачать: CL | DM;

Вниз

Update одной таблицы по условию из другой таблицы   Найти похожие ветки 

 
Юрий Зотов ©   (2009-05-18 15:25) [0]

Люди, что-то не соображу как сделать следующее

Есть таблица T1 с полями K11 (int), K12 (int), F1 (char) и таблица T2 с полями K21 (int), K22 (int), F2 (char). Поля K11 и K12 есть составной ключ некоего документа, такой же ключ составляют поля K21 и K22.

Требуется проапдейтить поле F1 в записях таблицы T1, удовлетворяющих условию:

T1.K11 = T2.K21
and
T1.K12 = T2.K22
and
T2.F2 = "НЕЧТО"

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


 
Игорь Шевченко ©   (2009-05-18 15:37) [1]

update t1 a set ...
where (a.k11, a.k12) in (select b.k21,b.k22 from t2 b where b.f2 = "НЕЧТО")

?


 
Игорь Шевченко ©   (2009-05-18 15:39) [2]

или exists

update t1 a set ...
where exists (select null from t2 b where b.k21 = a.k11 and b.k22 = a.k12 and b.f2 = "НЕЧТО")


 
Romkin ©   (2009-05-18 15:42) [3]

Чем апдейтить-то? :)
create table T1 (K11 int not null, K12 int not null, F1 char(<...>), primary key (K11, K12));
create table T2 (K21 int not null, K22 int not null, F2 char(<...>), primary key (K21, K22));

Вообще решение зависит от того, насколько полно поддерживается стандарт SQL, чего я о DB2 не знаю :(
1.
update T1 set F1 = <...>
where (K11, K12) in (select K21, K22 from T2 where F2= "НЕЧТО");

2.
update T1 set F1 = <...>
where exists (select * from T2 where T2.K21 = T1.K11 and T2.K22 = T1.K12 and T2.F2 = "НЕЧТО");


 
Romkin ©   (2009-05-18 15:43) [4]

:D


 
Игорь Шевченко ©   (2009-05-18 15:47) [5]

Romkin ©   (18.05.09 15:42) [3]

:D


 
Ega23 ©   (2009-05-18 16:06) [6]


> Требуется проапдейтить поле F1 в записях таблицы T1, удовлетворяющих
> условию:


А на что идёт Update F1? На значение T2.F2 (в данном случае - "НЕЧТО")?


 
sniknik ©   (2009-05-18 16:08) [7]

а явных джойнов DB2 не поддерживает?

UPDATE T1
SET T1.F1 = T1.F1 + T2.F1
FROM T1 INNER JOIN T2 ON (T1.K11 = T2.K21 and T1.K12 = T2.K22 and T2.F2 = "НЕЧТО")


имхо проще.


 
sniknik ©   (2009-05-18 16:11) [8]

> имхо проще.
да и быстрее должно быть чем с перезапросом на каждую запись.


 
Ega23 ©   (2009-05-18 16:14) [9]

Короче, должно сработать как-то так

Update T1 set
 T1.F1 = ...
from T1 inner join T2 on (T1.K11=T2.K21 and T1.K12=T2.K22 and T2.F2="НЕЧТО")


Только у меня сомнения насчёт того, что должно в   T1.F1 = ... стоять. Вроде, там и значение из T1 и из T2 должно быть.

З.Ы. Кстати. Так и не смог придумать тестового примера, дабы данные расходились...  :)


 
Ega23 ©   (2009-05-18 16:15) [10]


> sniknik ©   (18.05.09 16:08) [7]


:)


 
Anatoly Podgoretsky ©   (2009-05-18 16:18) [11]

Юрий Зотов ©   (18.05.09 15:25)  
До Update желательно написать работающий SELECT и тогда будет видно что проапдейтится и правильно, затем заменишь SELECT на Update


 
sniknik ©   (2009-05-18 16:18) [12]

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

UPDATE T1
SET T1.F1 = T1.F1 + T2.F1
FROM T1 INNER JOIN T2 ON (T1.K11 = T2.K21 and T1.K12 = T2.K22)
WHERE T2.F2 = "НЕЧТО"


так лучше. (опять имхо)


 
Юрий Зотов ©   (2009-05-18 17:15) [13]

Люди, вы гиганты. Спасибо.


 
Игорь Шевченко ©   (2009-05-18 18:43) [14]

sniknik ©   (18.05.09 16:18) [12]

Синтаксис UPDATE...FROM для меня несколько странен...


 
Ega23 ©   (2009-05-18 20:04) [15]


> Синтаксис UPDATE...FROM для меня несколько странен...


Должен быть. В ANSI, вроде как, присутствует.


 
Игорь Шевченко ©   (2009-05-18 20:41) [16]


> Должен быть. В ANSI, вроде как, присутствует


Вот хорошо тебе - ты SQL недавно изучаешь. А представь, что 20 с лишним лет ты видел один синтаксис, а потом всякие там ANSI придумывают нечто.

Кроме того синтаксис
UPDATE foo SET ...
WHERE

более очевиден, чем

UPDATE foo SET ...
FROM ...

В первом случае ты понимаешь, что надо обновить по условию, во втором впадаешь в ступор.


 
Petr V. Abramov ©   (2009-05-18 21:04) [17]


> Игорь Шевченко ©   (18.05.09 20:41) [16]


> а потом всякие там ANSI придумывают нечто.

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


 
sniknik ©   (2009-05-18 21:59) [18]

> А представь, что 20 с лишним лет ты видел один синтаксис, а потом всякие там ANSI придумывают нечто.
ну я поменьше 20-ти, но тем не менее начинал в базах с foxpro, где селект был даже не запросом, а открытием рабочей области, и только после "трансформировался" в подобие запроса, на самом деле была та же рабочая область просто с условиями (можно было повторно открыть такой "запрос" указав вместо запроса индекс рабочей области). и ничего адаптировался. и считаю, что то, что есть теперь, удобнее.

> более очевиден, чем
серьезно? и как тогда в "твоем" запросе "по условию"
> update t1 a set ...
> where (a.k11, a.k12) in (select b.k21,b.k22 from t2 b where b.f2 = "НЕЧТО")
без объединения использовать в апдейте данные другой таблицы, как здесь
> UPDATE T1
> SET T1.F1 = T1.F1 + T2.F1
> FROM T1 INNER JOIN T2 ON (T1.K11 = T2.K21 and T1.K12 = T2.K22)
> WHERE T2.F2 = "НЕЧТО"

очевидно объединение нужно, ну сделаешь ты его неявным но по сути будет тоже самое.

> вот их бы посадить запросы писать-читать, а не стандарты выдумывать.
думаешь их придумывают совсем неграмотные?


 
Игорь Шевченко ©   (2009-05-18 22:33) [19]


> но тем не менее начинал в базах с foxpro


Во-во.

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

Я повторюсь - лично для меня UPDATE ... FROM выглядит необычно. Точно также я буду спотыкаться на UPDATE ... WHERE CURRENT OF, хотя этому синтаксису поболе лет, чем UPDATE FROM, но все равно он идет от магнитных лент и настольных баз.


 
Игорь Шевченко ©   (2009-05-19 02:43) [20]

Кстати, о стандартах:

"Хотя большинство комитетов по стандартам, как правило, создают нечто ужасное, стандарт 1003.1 заметно отличается от общего правила в лучшую сторону....

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

(с) Эндрю Таненбаум


 
Anatoly Podgoretsky ©   (2009-05-19 09:18) [21]


> Игорь Шевченко ©   (18.05.09 22:33) [19]

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

Вот выписка из справки

> Определяет, что для определения критериев операции обновления
> используется таблица, представление или производный источник
> таблицы. Дополнительные сведения см. в разделе FROM (Transact-
> SQL).
>
> Если обновляемый объект тот же самый, что и объект в предложении
> FROM, и в предложении FROM имеется только одна ссылка на
> этот объект, псевдоним объекта указывать необязательно.
> Если обновляемый объект встречается в предложении FROM несколько
> раз, одна и только одна ссылка на этот объект не должна
> указывать псевдоним таблицы. Все остальные ссылки на объект
> в предложении FROM должны включать псевдоним объекта.


А вот дополнение

> Указывает таблицы, представления, производные таблицы и
> соединяемые таблицы, которые используются в инструкциях
> DELETE, SELECT и UPDATE. В инструкции SELECT требуется предложение
> FROM, за исключением тех случаев, когда список выбора содержит
> только константы, переменные и арифметические выражения
> (без имен столбцов).


 
Ega23 ©   (2009-05-19 10:16) [22]

Я сегодня с утра так немного подумал...
Вобщем, у Юрия условие какое-то странное.

T1.K11 = T2.K21
and
T1.K12 = T2.K22
and
T2.F2 = "НЕЧТО"


"НЕЧТО" - избыточное условие, и так всё сработает (в случае, когда таких сочетаний больше нуля).
Либо надо что-то типа

T1.K11 = T2.K21
and
T1.K12 = T2.K22
and
T1.F1=T2.F2
and
T2.F2 = "НЕЧТО"


 
Игорь Шевченко ©   (2009-05-19 11:01) [23]


> Предложи другой вариант синтаксиса


собственно в самом начале предложил


 
palva ©   (2009-05-19 11:12) [24]


> Ega23 ©   (19.05.09 10:16) [22]

Что-то я не понял, почему условие лишнее.
Надо обновить только те записи T1, которые после соединения (один к одному) дают T2.F2 = "НЕЧТО"
Как же можно этого добиться без указания "НЕЧТО"


 
Ega23 ©   (2009-05-19 11:15) [25]


> Что-то я не понял, почему условие лишнее.


Всё нормально, я уже уточнил условие. Просто я [0] не так понял.
[22] - снято.


 
Anatoly Podgoretsky ©   (2009-05-19 11:54) [26]


> собственно в самом начале предложил

Если ты имеешь в виду [1] и [2], то не вижу


 
Игорь Шевченко ©   (2009-05-19 12:04) [27]

Anatoly Podgoretsky ©   (19.05.09 11:54) [26]


> Если ты имеешь в виду [1] и [2], то не вижу



> Предложи другой вариант синтаксиса, где источников для обновления
> больше одного и они не только простые таблицы, но соединения,
>  при том множественные на одну и туже таблицу.


Переведи пожалуйста эту фразу. Я не понимаю, что имеется в виду - одним UPDATE изменять несколько таблиц или изменять одну таблицу, но критерией для отбора записей для изменения является N таблиц ?
Во втором случае - [1] или [2].


 
Anatoly Podgoretsky ©   (2009-05-19 12:31) [28]

> Игорь Шевченко  (19.05.2009 12:04:27)  [27]

set f1=t2.f1, f2=t3.f2,... fN=tN.fN
где tX - это или просто таблицы, или представления, или соединения с другими таблицами по JOIN при том возможно несколько соединений с одной и той же таблицей.
где количество источников столько сколько нужно и нет ограничения на тип и без вложеных запросов. Вот для этого и нужно ключевое слово FROM что бы можно было создать и использовать алиасы для указания источника. Или другими словами справа может быть любая структура допустимая для SELECT ... FROM список источников.


 
Игорь Шевченко ©   (2009-05-19 14:13) [29]


> set f1=t2.f1, f2=t3.f2,... fN=tN.fN
> где tX - это или просто таблицы, или представления, или
> соединения с другими таблицами по JOIN при том возможно
> несколько соединений с одной и той же таблицей.
> где количество источников столько сколько нужно и нет ограничения
> на тип и без вложеных запросов. Вот для этого и нужно ключевое
> слово FROM что бы можно было создать и использовать алиасы
> для указания источника. Или другими словами справа может
> быть любая структура допустимая для SELECT ... FROM список
> источников.


В этом случае гораздо проще использовать UPDATE ... WHERE CURRENT OF


 
Anatoly Podgoretsky ©   (2009-05-19 14:29) [30]

> Игорь Шевченко  (19.05.2009 14:13:29)  [29]

Может быть и так, но это синтаксис Оракла и я не уверен на присутствие в стандарте или в других SQL серверах, в T-SQL этого формата нет и я даже не представляю ее синтаксиса.


 
sniknik ©   (2009-05-19 14:35) [31]

> В этом случае гораздо проще использовать UPDATE ... WHERE CURRENT OF
проще? объединение с курсором и правилами объединения описанными где то "в стороне", да это имхо еще более неявно чем неявное объединение...

для примера, кто не в курсе
http://www.techonthenet.com/oracle/cursors/current_of.php

ну или покажи на примере аналог запроса из [12] с CURRENT OF, так чтобы он был проще для восприятия.

p.s. это в тебе просто говорит неприятие нового, а не реальное знание, что что-то проще.


 
sniknik ©   (2009-05-19 14:40) [32]

> но это синтаксис Оракла
был рожден в оракле и помрет в нем же, а если бы это было реально удобнее и проще то давно бы уже повторили, а может и стандартом сделали. ведь довольно старая конструкция, время осмыслить было.


 
Ega23 ©   (2009-05-19 14:45) [33]


> в T-SQL этого формата нет и я даже не представляю ее синтаксиса.


Чё-это нет-то сразу?

Использование инструкции UPDATE с предложением FROM
Результаты инструкции UPDATE не определены, если инструкция включает предложение FROM, в котором для каждого вхождения обновляемого столбца не задано единственное значение, то есть если инструкция UPDATE не является детерминированной. Например, в инструкции UPDATE следующего сценария обе строки в Table1 удовлетворяют условиям предложения FROM в инструкции UPDATE, но не определено, какая строка из Table1 используется для обновления строки в Table2.

USE AdventureWorks;
GO
IF OBJECT_ID ("dbo.Table1", "U") IS NOT NULL
   DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ("dbo.Table2", "U") IS NOT NULL
   DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
   (ColA int NOT NULL, ColB decimal(10,3) NOT NULL);
GO
CREATE TABLE dbo.Table2
   (ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES(1, 10.0);
INSERT INTO dbo.Table1 VALUES(1, 20.0);
INSERT INTO dbo.Table2 VALUES(1, 0.0);
GO
UPDATE dbo.Table2
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2
   INNER JOIN dbo.Table1
   ON (dbo.Table2.ColA = dbo.Table1.ColA);
GO
SELECT ColA, ColB
FROM dbo.Table2;



То же самое может произойти при сочетании предложений FROM и WHERE CURRENT OF. В следующем примере обе строки в Table2 удовлетворяют условиям предложения FROM в инструкции UPDATE. Не определено, какая строка из Table2 должна использоваться для обновления строки в Table1.

USE AdventureWorks;
GO
IF OBJECT_ID ("dbo.Table1", "U") IS NOT NULL
   DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ("dbo.Table2", "U") IS NOT NULL
   DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
   (c1 int PRIMARY KEY NOT NULL, c2 int NOT NULL);
GO
CREATE TABLE dbo.Table2
   (d1 int PRIMARY KEY NOT NULL, d2 int NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES (1, 10);
INSERT INTO dbo.Table2 VALUES (1, 20);
INSERT INTO dbo.Table2 VALUES (2, 30);
GO
DECLARE abc CURSOR LOCAL FOR
   SELECT c1, c2
   FROM dbo.Table1;
OPEN abc;
FETCH abc;
UPDATE dbo.Table1
SET c2 = c2 + d2
FROM dbo.Table2
WHERE CURRENT OF abc;
GO
SELECT c1, c2 FROM dbo.Table1;
GO


Только курсор для этого ещё открывать - некузяво как-то для T-SQL


 
Игорь Шевченко ©   (2009-05-19 14:45) [34]

Anatoly Podgoretsky ©   (19.05.09 14:29) [30]


> Может быть и так, но это синтаксис Оракла и я не уверен
> на присутствие в стандарте


Вообще-то это синтаксис SQL-92

sniknik ©   (19.05.09 14:35) [31]


> p.s. это в тебе просто говорит неприятие нового, а не реальное
> знание, что что-то проще.


Безусловно. Если ты читаешь внимательно, то увидишь, что я говорю исключительно о своем впечатлении. Надеюсь, на этой благостной ноте мы закончим дискуссию.

P.S. Я еще использую синтаксис с (+) вместо OUTER JOIN в силу присущего мне консерватизма.


 
Petr V. Abramov ©   (2009-05-20 11:22) [35]


> sniknik ©   (18.05.09 21:59) [18]


> думаешь их придумывают совсем неграмотные?

ну почему, минимум писАть умеют.

> P.S. Я еще использую синтаксис с (+) вместо OUTER JOIN в
> силу присущего мне консерватизма.

а я думал, потому что букаф меньше и запрос читабельней


 
Ega23 ©   (2009-05-20 11:37) [36]


> и запрос читабельней


Ой, Петь, это крайне спорный вопрос насчет читабельности. Я конечно понимаю, что в чужой монастырь (Oracle, Postgres, MSSQL или ещё что-нибудь) со своим уставом соваться не положено, но Outer Join - он даже в Access Outer Join. А вот (+) - далеко не везде...  :)


 
ANB   (2009-05-20 11:42) [37]

update с from штука удобная, я пользовался ей в MS SQL.
В оракле ее нету. Но в оракле можно прекрасно обойтись и без оной - либо через IN либо через пл/скл скрипт.
А вот в MS SQL скрипт писать с курсором запаришься, да и курсоры в нем хреново реализованы (о чем написано в BOL), посему, видимо, и реализовали апдейт с фромом.


 
ANB   (2009-05-20 11:46) [38]


> Ой, Петь, это крайне спорный вопрос насчет читабельности.
>  Я конечно понимаю, что в чужой монастырь (Oracle, Postgres,
>  MSSQL или ещё что-нибудь) со своим уставом соваться не
> положено, но Outer Join - он даже в Access Outer Join. А
> вот (+) - далеко не везде...  :)

Ну и что, что не везде. Один хрен, попытка писать запросы так, чтобы выполнялись на всех СУБД - полностью бестолковая затея.
Зато с (+) на оракле и читать удобнее и писать меньше.


 
sniknik ©   (2009-05-20 11:52) [39]

если считать, что читабельнее то где меньше букв, то надо признать что perl самый понятный язык, причем в самой его "жесткой" форме, когда в строчку умещается целая программа. (а еще круче если перл скрипт выполняется прям из архива, архив будет прям эталоном читабельности... и проще всего прямо в его кодах и писать)
и C на порядок понятнее дельфей (ну как же вместо begin (6) пишут { (1), и т.д.).


 
ANB   (2009-05-20 12:00) [40]


> Зато с (+) на оракле и читать удобнее и писать меньше.



> и C на порядок понятнее дельфей (ну как же вместо begin
> (6) пишут { (1), и т.д.).

Всегда считал C понятнее паскаля.



Страницы: 1 2 вся ветка

Текущий архив: 2010.08.27;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.056 c
2-1267511178
@!!ex
2010-03-02 09:26
2010.08.27
Как изменить внешний вид TPageControl?


15-1267515795
@!!ex
2010-03-02 10:43
2010.08.27
Опять AOL бунтует?


15-1273177800
Юрий
2010-05-07 00:30
2010.08.27
С днем рождения ! 7 мая 2010 пятница


15-1270289462
Урсулапов_
2010-04-03 14:11
2010.08.27
Symantec и Mail.ru агент


15-1269604734
Кто б сомневался
2010-03-26 14:58
2010.08.27
Ускорение загрузки сайтов в 5 - 8 раз в Opera