powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / UPDATE FROM обновляет по первому значению результата джойна
5 сообщений из 30, страница 2 из 2
UPDATE FROM обновляет по первому значению результата джойна
    #39813657
Ёжик25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Посетитель,

потому что такое поведение нелогично с точки зрения логики и с точки зрения реляционной теории, и не очевидно. Знать наизусть всю документацию нереально. А конструкция не выдает ошибки.
Как с теми же переменными, которые ругаются, когда пытаешься присвоить им несколько значений. По той же логике, по сути мы обновляем запись в целевой таблице некой "переменной", которая приняла в операции UPDATE значение, прочитанное из другой таблицы.
Сугубо имхо))).
...
Рейтинг: 0 / 0
UPDATE FROM обновляет по первому значению результата джойна
    #39813662
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25Посетитель,

потому что такое поведение нелогично с точки зрения логики и с точки зрения реляционной теории, и не очевидно. Знать наизусть всю документацию нереально. А конструкция не выдает ошибки.
Как с теми же переменными, которые ругаются, когда пытаешься присвоить им несколько значений. По той же логике, по сути мы обновляем запись в целевой таблице некой "переменной", которая приняла в операции UPDATE значение, прочитанное из другой таблицы.
Сугубо имхо))).Если написать SELECT @V=V FROM T, то SELECT может вернуть хоть миллиард записей, - присвоится последнее (я, кажется, это уже говорил).
А вот если SET @V=(SELECT V FROM T)то SELECT в скобках обязан вернуть не более одного значения,
ибо это скалярное выражение. Иначе обругается.
...
Рейтинг: 0 / 0
UPDATE FROM обновляет по первому значению результата джойна
    #39813683
Ёжик25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iapЁжик25Посетитель,

потому что такое поведение нелогично с точки зрения логики и с точки зрения реляционной теории, и не очевидно. Знать наизусть всю документацию нереально. А конструкция не выдает ошибки.
Как с теми же переменными, которые ругаются, когда пытаешься присвоить им несколько значений. По той же логике, по сути мы обновляем запись в целевой таблице некой "переменной", которая приняла в операции UPDATE значение, прочитанное из другой таблицы.
Сугубо имхо))).Если написать SELECT @V=V FROM T, то SELECT может вернуть хоть миллиард записей, - присвоится последнее (я, кажется, это уже говорил).
А вот если SET @V=(SELECT V FROM T)то SELECT в скобках обязан вернуть не более одного значения,
ибо это скалярное выражение. Иначе обругается.

Забавно, а вот PG присваивает первое значение при SELECT @V=V FROM T.
...
Рейтинг: 0 / 0
UPDATE FROM обновляет по первому значению результата джойна
    #39813844
step_ks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25, может еще и так быть
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
if object_id('tempdb..#src') is not null Drop table #src;
if object_id('tempdb..#trg') is not null drop table #trg;
GO

create table #src (id int, type int, value1 nvarchar(20),value2 nvarchar(20))
insert into #src (id,type,value1,value2)  values (10,8,'888',null), (10,8,'777','ccc'), (10,8,'999',null), (111,8,'999',null)

create table #trg (id int, type int, value1 nvarchar(20),value2 nvarchar(20))
insert into #trg (id,type,value1) values (10,8,'111')


select * from #src
select * from #trg

update #trg set
        value1 = #src.value1,
        value2 = #src.value2
    from #trg join #src on #trg.id = #src.id and #trg.type=#src.type;

select * from #trg
GO



Результаты:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
-- select * from #src
id          type        value1               value2
----------- ----------- -------------------- --------------------
10          8           888                  NULL
10          8           777                  ccc
10          8           999                  NULL
111         8           999                  NULL

-- select * from #trg
id          type        value1               value2
----------- ----------- -------------------- --------------------
10          8           111                  NULL


-- select * from #trg после update
id          type        value1               value2
----------- ----------- -------------------- --------------------
10          8           888                  ccc
...
Рейтинг: 0 / 0
UPDATE FROM обновляет по первому значению результата джойна
    #39813849
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25потому что такое поведение нелогично с точки зрения логики и с точки зрения реляционной теории, и не очевидно. Знать наизусть всю документацию нереально. А конструкция не выдает ошибки.Да, наверное, с точки зрения чистой теории это неправильно.
Но так было сделано во всех без исключения реализациях SQL, наверное, потому, что UPDATE с джойнами часто даёт повторяющиеся значения, и генерить ошибку было бы непрактично. Поэтому сделали обновление случайной записью.

То есть это теоретически неправильно, но вполне логично.

Тем более, не забывайте, когда это было сделано - в 70-е, 80-е. Вспомните, что такое SQL, и зачем он появился.
Тогда же, например, придумали понятие "владелец объекта", что бы 2 бухгалтера, набирая запросы в SQL для составления ведомости на зарплату, или сведения квартального баланса, не мешали друг другу.

А MERGE, или скалярный подзапрос, или присвоегие переменной в SET, придумали намного позже, это более сложные конструкции, они расчитаны на программистов, а не бухгалтеров, и они более строгие.
...
Рейтинг: 0 / 0
5 сообщений из 30, страница 2 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / UPDATE FROM обновляет по первому значению результата джойна
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]