![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Update одной таблицы по условию из другой таблицы [DB2]
Юрий Зотов © (2009-05-18 15:25:00)Люди, что-то не соображу как сделать следующее
Есть таблица 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 написать. Поможите кто добрый, плз.
sniknik (2009-05-20 11:52:00) [41]если считать, что читабельнее то где меньше букв, то надо признать что perl самый понятный язык, причем в самой его "жесткой" форме, когда в строчку умещается целая программа. (а еще круче если перл скрипт выполняется прям из архива, архив будет прям эталоном читабельности... и проще всего прямо в его кодах и писать)
и C на порядок понятнее дельфей (ну как же вместо begin (6) пишут { (1), и т.д.).
ANB (2009-05-20 11:46:00) [42]
> Ой, Петь, это крайне спорный вопрос насчет читабельности.
> Я конечно понимаю, что в чужой монастырь (Oracle, Postgres,
> MSSQL или ещё что-нибудь) со своим уставом соваться не
> положено, но Outer Join - он даже в Access Outer Join. А
> вот (+) - далеко не везде... :)
Ну и что, что не везде. Один хрен, попытка писать запросы так, чтобы выполнялись на всех СУБД - полностью бестолковая затея.
Зато с (+) на оракле и читать удобнее и писать меньше.
ANB (2009-05-20 11:42:00) [43]update с from штука удобная, я пользовался ей в MS SQL.
В оракле ее нету. Но в оракле можно прекрасно обойтись и без оной - либо через IN либо через пл/скл скрипт.
А вот в MS SQL скрипт писать с курсором запаришься, да и курсоры в нем хреново реализованы (о чем написано в BOL), посему, видимо, и реализовали апдейт с фромом.
Ega23 (2009-05-20 11:37:00) [44]
> и запрос читабельней
Ой, Петь, это крайне спорный вопрос насчет читабельности. Я конечно понимаю, что в чужой монастырь (Oracle, Postgres, MSSQL или ещё что-нибудь) со своим уставом соваться не положено, но Outer Join - он даже в Access Outer Join. А вот (+) - далеко не везде... :)
Petr V. Abramov (2009-05-20 11:22:00) [45]
> sniknik © (18.05.09 21:59) [18]
> думаешь их придумывают совсем неграмотные?
ну почему, минимум писАть умеют.
> P.S. Я еще использую синтаксис с (+) вместо OUTER JOIN в
> силу присущего мне консерватизма.
а я думал, потому что букаф меньше и запрос читабельней
Игорь Шевченко (2009-05-19 14:45:00) [46]Anatoly Podgoretsky © (19.05.09 14:29) [30]
> Может быть и так, но это синтаксис Оракла и я не уверен
> на присутствие в стандарте
Вообще-то это синтаксис SQL-92
sniknik © (19.05.09 14:35) [31]
> p.s. это в тебе просто говорит неприятие нового, а не реальное
> знание, что что-то проще.
Безусловно. Если ты читаешь внимательно, то увидишь, что я говорю исключительно о своем впечатлении. Надеюсь, на этой благостной ноте мы закончим дискуссию.
P.S. Я еще использую синтаксис с (+) вместо OUTER JOIN в силу присущего мне консерватизма.
Ega23 (2009-05-19 14:45:00) [47]
> в 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
sniknik (2009-05-19 14:40:00) [48]> но это синтаксис Оракла
был рожден в оракле и помрет в нем же, а если бы это было реально удобнее и проще то давно бы уже повторили, а может и стандартом сделали. ведь довольно старая конструкция, время осмыслить было.
sniknik (2009-05-19 14:35:00) [49]> В этом случае гораздо проще использовать UPDATE ... WHERE CURRENT OF
проще? объединение с курсором и правилами объединения описанными где то "в стороне", да это имхо еще более неявно чем неявное объединение...
для примера, кто не в курсе
http://www.techonthenet.com/oracle/cursors/current_of.php
ну или покажи на примере аналог запроса из [12] с CURRENT OF, так чтобы он был проще для восприятия.
p.s. это в тебе просто говорит неприятие нового, а не реальное знание, что что-то проще.
Anatoly Podgoretsky (2009-05-19 14:29:00) [50]> Игорь Шевченко (19.05.2009 14:13:29) [29]
Может быть и так, но это синтаксис Оракла и я не уверен на присутствие в стандарте или в других SQL серверах, в T-SQL этого формата нет и я даже не представляю ее синтаксиса.
Игорь Шевченко (2009-05-19 14:13:00) [51]
> set f1=t2.f1, f2=t3.f2,... fN=tN.fN
> где tX - это или просто таблицы, или представления, или
> соединения с другими таблицами по JOIN при том возможно
> несколько соединений с одной и той же таблицей.
> где количество источников столько сколько нужно и нет ограничения
> на тип и без вложеных запросов. Вот для этого и нужно ключевое
> слово FROM что бы можно было создать и использовать алиасы
> для указания источника. Или другими словами справа может
> быть любая структура допустимая для SELECT ... FROM список
> источников.
В этом случае гораздо проще использовать UPDATE ... WHERE CURRENT OF
Anatoly Podgoretsky (2009-05-19 12:31:00) [52]> Игорь Шевченко (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 12:04:00) [53]Anatoly Podgoretsky © (19.05.09 11:54) [26]
> Если ты имеешь в виду [1] и [2], то не вижу
> Предложи другой вариант синтаксиса, где источников для обновления
> больше одного и они не только простые таблицы, но соединения,
> при том множественные на одну и туже таблицу.
Переведи пожалуйста эту фразу. Я не понимаю, что имеется в виду - одним UPDATE изменять несколько таблиц или изменять одну таблицу, но критерией для отбора записей для изменения является N таблиц ?
Во втором случае - [1] или [2].
Anatoly Podgoretsky (2009-05-19 11:54:00) [54]
> собственно в самом начале предложил
Если ты имеешь в виду [1] и [2], то не вижу
Ega23 (2009-05-19 11:15:00) [55]
> Что-то я не понял, почему условие лишнее.
Всё нормально, я уже уточнил условие. Просто я [0] не так понял.
[22] - снято.
palva (2009-05-19 11:12:00) [56]
> Ega23 © (19.05.09 10:16) [22]
Что-то я не понял, почему условие лишнее.
Надо обновить только те записи T1, которые после соединения (один к одному) дают T2.F2 = 'НЕЧТО'
Как же можно этого добиться без указания 'НЕЧТО'
Игорь Шевченко (2009-05-19 11:01:00) [57]
> Предложи другой вариант синтаксиса
собственно в самом начале предложил
Ega23 (2009-05-19 10:16:00) [58]Я сегодня с утра так немного подумал...
Вобщем, у Юрия условие какое-то странное.
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 = 'НЕЧТО'
Anatoly Podgoretsky (2009-05-19 09:18:00) [59]
> Игорь Шевченко © (18.05.09 22:33) [19]
Предложи другой вариант синтаксиса, где источников для обновления больше одного и они не только простые таблицы, но соединения, при том множественные на одну и туже таблицу. Ведь все равно придется придумывать какой то синтаксис, пускай без естественного FROM
Вот выписка из справки
> Определяет, что для определения критериев операции обновления
> используется таблица, представление или производный источник
> таблицы. Дополнительные сведения см. в разделе FROM (Transact-
> SQL).
>
> Если обновляемый объект тот же самый, что и объект в предложении
> FROM, и в предложении FROM имеется только одна ссылка на
> этот объект, псевдоним объекта указывать необязательно.
> Если обновляемый объект встречается в предложении FROM несколько
> раз, одна и только одна ссылка на этот объект не должна
> указывать псевдоним таблицы. Все остальные ссылки на объект
> в предложении FROM должны включать псевдоним объекта.
А вот дополнение
> Указывает таблицы, представления, производные таблицы и
> соединяемые таблицы, которые используются в инструкциях
> DELETE, SELECT и UPDATE. В инструкции SELECT требуется предложение
> FROM, за исключением тех случаев, когда список выбора содержит
> только константы, переменные и арифметические выражения
> (без имен столбцов).
Игорь Шевченко (2009-05-19 02:43:00) [60]Кстати, о стандартах:
"Хотя большинство комитетов по стандартам, как правило, создают нечто ужасное, стандарт 1003.1 заметно отличается от общего правила в лучшую сторону....
Документ 1003.1 написан так, чтобы как разработчики операционной системы, так и создатели программного обеспечения были способны его понять, что также ново в мире стандартов, хотя в настоящее время уже полным ходом ведется работа по исправлению этого нестандартного для стандартов свойства."
(с) Эндрю Таненбаум