Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.075 c
15-1265369204
Тайлер Дерден
2010-02-05 14:26
2010.08.27
1С, терминальный сервер и печать


2-1267982007
NBAH1990
2010-03-07 20:13
2010.08.27
Ошибка при передачи данных по TCP протоколу


15-1264411731
KilkennyCat
2010-01-25 12:28
2010.08.27
Нет ли у кого в Питере ненужного сломанного принтера


15-1265790438
12
2010-02-10 11:27
2010.08.27
Переведите пожалуйста на любой диалект VBA ..


2-1267882176
nikih22
2010-03-06 16:29
2010.08.27
SERVESOCKET и CLIENTSOKEТ и интернет





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский