Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите написать Merge !  [new]
Dimais
Member

Откуда:
Сообщений: 227
Собственно есть 2 таблицы:
Основная - #temp
и таблица изменений - #chg

id - уникальный ключ в таблице #temp, ts - некий time_stamp (чем он больше, тем позднее была транзакция модификации данных)
если ts null значит запись удалили, если нет то либо это update либо вставка новой записи в таблицу #temp (думаю из примера ясно что есть что)

create table #temp (id int, name varchar(50), ts int)
create table #chg (id int, name varchar(50), ts int)
--insert into #temp select 4, 'Max', 12


insert into #temp
select 1,'Dima',45
union select 2,'Anna',34
union select 3,'Andrey',67
union select 4,'Max',12


insert into #chg
select 1,'Dima I.',68
union select 1,'Dima Ivanov',69
union select 2,'Anna Petrova',70
union select 5,'Mixa',71
union select 6,'Ira',73
union select 6,'Ira A.',74
union select 4,'Max D.',75
union select 4,	NULL,NULL
union select 7,'Oleg',76
union select 7,'Oleg N',77
union select 7,NULL,NULL


--truncate table #temp
--truncate table #chg


select * from #temp
select * from #chg

Как накатить все эти изменения в таблице #chg на таблицу #temp одной командой Merge ... и вообще возможно ли это?


Моя фантазия иссякла на :
merge #temp t
using (select top 1 with ties * from #chg order by ROW_NUMBER () over(partition by id order by isnull(ts, 999999999) desc)) s
on (s.id = t.id)
WHEN MATCHED AND s.ts is null THEN
DELETE
--WHEN MATCHED AND s.ts > t.ts THEN
--DELETE
WHEN NOT MATCHED BY TARGET THEN
INSERT (id, name, ts) VALUES (s.id, s.name, s.ts);
19 сен 11, 20:01    [11301404]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
Dimais
Member

Откуда:
Сообщений: 227
Фактически нужно что бы merge выполнял только insert и delete !
19 сен 11, 20:06    [11301421]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
kinglion
Member

Откуда:
Сообщений: 16
Dimais,

Если Вы предполагаете, что MERGE будет у Вас выполнять другие действия, то запустите данный код в транзакции с ROLLBACK и посмотрите, что он делает
19 сен 11, 23:01    [11301940]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
kinglion
Member

Откуда:
Сообщений: 16
Dimais,

merge #temp t
using (select top 1 with ties * from #chg order by ROW_NUMBER () over(partition by id order by isnull(ts, 999999999) desc)) s
on (s.id = t.id)
WHEN MATCHED AND s.ts is null THEN
DELETE
WHEN NOT MATCHED BY TARGET AND s.ts is not null THEN
INSERT (id, name, ts) VALUES (s.id, s.name, s.ts);
19 сен 11, 23:07    [11301955]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
Dimais
Member

Откуда:
Сообщений: 227
Не то ... результата должен быть таким:
1,'Dima Ivanov',69 
2,'Anna Petrova',70
3,'Andrey',67
5,'Mixa',71
6,'Ira A.',74
20 сен 11, 10:05    [11302940]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
Dimais
Member

Откуда:
Сообщений: 227
результат :-)
20 сен 11, 10:06    [11302948]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
Dimais
Member

Откуда:
Сообщений: 227
Получилось ...
merge #temp t
using (select top 1 with ties * from #chg order by ROW_NUMBER() over(partition by id order by isnull(ts, 999999999) desc)) s
on (s.id = t.id)
WHEN MATCHED AND s.ts is null THEN
DELETE
WHEN MATCHED THEN
UPDATE set t.name = s.name, t.ts = s.ts
WHEN NOT MATCHED BY TARGET AND s.ts is not null THEN
INSERT (id, name, ts) VALUES (s.id, s.name, s.ts);

А как без Update-а ... ?
20 сен 11, 10:57    [11303286]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
iljy
Member

Откуда:
Сообщений: 8711
Dimais
А как без Update-а ... ?

Ээээ.... в каком смысле? Не нужен UPDATE - так уберите.
20 сен 11, 11:07    [11303376]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
Dimais
Member

Откуда:
Сообщений: 227
В том смысле что если, допустим, существовала запись в таблице и её 5 раз проапдейтили, то я хочу
просто удалить текущую запись и вставить последнюю актуальную, вместо операции UPDATE
20 сен 11, 11:18    [11303483]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
iljy
Member

Откуда:
Сообщений: 8711
Dimais
В том смысле что если, допустим, существовала запись в таблице и её 5 раз проапдейтили, то я хочу
просто удалить текущую запись и вставить последнюю актуальную, вместо операции UPDATE

Так. Не морочьте себе голову. Сервер разберется в такой ситуации гораздо лучше вас и ничего 5 раз апдейтить не будет (да и не сможет, уберите top и посмотрите, что вам скажут).
20 сен 11, 11:24    [11303532]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
Dimais
Member

Откуда:
Сообщений: 227
А я и не утверждаю что он будет что то 5 раз апдейтить, я для этого и использую конструкцию
top 1 with ties .... order by row_number() ... чтобы выбрать последнюю актуальную запись.
Просто я хочу update заменить на Delete + Insert и все !
20 сен 11, 11:40    [11303674]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
iljy
Member

Откуда:
Сообщений: 8711
Dimais
Просто я хочу update заменить на Delete + Insert и все !

Зачем?
20 сен 11, 11:46    [11303745]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать Merge !  [new]
Dimais
Member

Откуда:
Сообщений: 227
iljy
Зачем?

Да вот теперь и сам думаю .... зачем, казалось будет быстрее работать,
а теперь задумался ... а с чего бы это ?! :-)
20 сен 11, 11:51    [11303795]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить