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

Откуда:
Сообщений: 9
Не могу понять как работает MERGE.
Если у меня в исходной талице есть несколько версий одной и той же строки, то merge не подходит для того чтобы слить их вместе?
Declare @target AS TABLE ([Id] [bigint], [Version] [bigint])
Declare @source AS TABLE ([Id] [bigint],[Version] [bigint])

insert into @source values(0,1)
insert into @source values(0,2)

SELECT  * FROM @source

MERGE @target AS target
USING @source AS source
        ON target.Id = source.Id
WHEN MATCHED AND source.Version > target.Version THEN
        UPDATE SET  target.Version = source.Version
WHEN NOT MATCHED BY TARGET THEN
        INSERT ([Id],[Version])
        VALUES ([Id],[Version]);

SELECT  * FROM @target


Исходная таблица:

-------------
| ID |Version|
-------------
| 0 | 1 |
------------
| 0 | 2 |
------------

В результате я ожидаю получить это

-------------
| ID |Version|
-------------
| 0 | 2 |
------------

Но получаю тоже что и в исходной

Почему так происходит?
4 июн 17, 20:40    [20538374]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
invm
Member

Откуда: Москва
Сообщений: 9127
Alew
Почему так происходит?
Потому что таблицы target и source соединяются однократно и ветки when применяются к каждой строке результата этого соединения.
4 июн 17, 21:32    [20538462]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
bideveloper
Member

Откуда:
Сообщений: 485
Alew, вашу задачу можно решить, например, так:

select id, version from @source as s1
where version in (select max(version ) from @source as s2 where s2.id= s1.id)
5 июн 17, 01:37    [20538840]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
bideveloper
Alew, вашу задачу можно решить, например, так:

select id, version from @source as s1
where version in (select max(version ) from @source as s2 where s2.id= s1.id)

А за такое руки бы вам оторвать да пришить в правильное место.
5 июн 17, 11:04    [20539460]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
bideveloper
Member

Откуда:
Сообщений: 485
Руслан Дамирович,
напишите свой вариант и посмотрим, кому что нужно оторвать )
5 июн 17, 14:42    [20540442]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
LoopN
Guest
Руслан Дамирович
bideveloper
Alew, вашу задачу можно решить, например, так:

select id, version from @source as s1
where version in (select max(version ) from @source as s2 where s2.id= s1.id)

А за такое руки бы вам оторвать да пришить в правильное место.

Да, мне тоже интересно. MSSQL 2008, покажи вариант без отрыва рук.
5 июн 17, 14:46    [20540466]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
Remind
Member

Откуда: UK
Сообщений: 523
Alew,

with cte as 
(
  select *, row_number() over (partition by id order by version desc) as rn
  from @source s
)
MERGE @target as target
USING (select * from cte where rn = 1) as source
...
5 июн 17, 14:49    [20540488]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
LoopN
Guest
И не такой

select top 1 with ties id, version from @source as s1
ORDER BY RANK() OVER(partition by id order by version desc)
5 июн 17, 14:49    [20540490]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
bideveloper , LooopN
Господа, да вы из тех, кто писюном орехи колет... Тут медицина бессильна.
5 июн 17, 15:13    [20540600]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
Руслан Дамирович
bideveloper , LooopN
Господа, да вы из тех, кто писюном орехи колет... Тут медицина бессильна.

так и быть, посвящай нас
5 июн 17, 15:26    [20540657]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
LoopN
Guest
Руслан Дамирович
bideveloper , LooopN
Господа, да вы из тех, кто писюном орехи колет... Тут медицина бессильна.

Пока слышим только звон, вариант с top 1 ties точно будет самый быстрый. Быстрее ты не сделаешь.
5 июн 17, 15:29    [20540669]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
iap
Member

Откуда: Москва
Сообщений: 46954
LoopN
Руслан Дамирович
bideveloper , LooopN
Господа, да вы из тех, кто писюном орехи колет... Тут медицина бессильна.

Пока слышим только звон, вариант с top 1 ties точно будет самый быстрый. Быстрее ты не сделаешь.
Не знаю, какую задачу вы тут решаете, уж не обессудьте,
но если речь идёт о запросе четырьмя постами выше, то лучше будет работать так:
WITH CTE AS(SELECT N=RANK()OVER(PARTITION BY id ORDER BY version DESC),* FROM @source)
SELECT id, version
FROM CTE
WHERE N=1;
5 июн 17, 15:48    [20540747]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
LoopN
Guest
iap
LoopN
пропущено...

Пока слышим только звон, вариант с top 1 ties точно будет самый быстрый. Быстрее ты не сделаешь.
Не знаю, какую задачу вы тут решаете, уж не обессудьте,
но если речь идёт о запросе четырьмя постами выше, то лучше будет работать так:
WITH CTE AS(SELECT N=RANK()OVER(PARTITION BY id ORDER BY version DESC),* FROM @source)
SELECT id, version
FROM CTE
WHERE N=1;

Это ничем не лучше, это практически тоже самое. Там выше уже был такой вариант, завернули его.
5 июн 17, 15:51    [20540761]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
iap
Member

Откуда: Москва
Сообщений: 46954
LoopN
iap
пропущено...
Не знаю, какую задачу вы тут решаете, уж не обессудьте,
но если речь идёт о запросе четырьмя постами выше, то лучше будет работать так:
WITH CTE AS(SELECT N=RANK()OVER(PARTITION BY id ORDER BY version DESC),* FROM @source)
SELECT id, version
FROM CTE
WHERE N=1;


Это ничем не лучше, это практически тоже самое. Там выше уже был такой вариант, завернули его.
На чём основано сие утверждение?
Мы тут это много раз сравнивали.
5 июн 17, 15:53    [20540773]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
LoopN
Guest
iap
LoopN
пропущено...

Это ничем не лучше, это практически тоже самое. Там выше уже был такой вариант, завернули его.
На чём основано сие утверждение?
Мы тут это много раз сравнивали.

И к чему пришли? top 1 ties не должен быть медленее rn=1, если сравнивать эти два запрсоа оптимизатор cost обычно ставит меньше у ties (имхо). Нужны пруфы билли.
5 июн 17, 15:59    [20540797]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
iap
Member

Откуда: Москва
Сообщений: 46954
LoopN
iap
пропущено...
На чём основано сие утверждение?
Мы тут это много раз сравнивали.

И к чему пришли? top 1 ties не должен быть медленее rn=1, если сравнивать эти два запрсоа оптимизатор cost обычно ставит меньше у ties (имхо). Нужны пруфы билли.
Поискать по форуму не проблема.
5 июн 17, 16:15    [20540858]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
LoopN
Guest
create table t
(
	i int NOT NULL,
	J int NOT NULL
)

insert into t(i,j)
select ABS(CHECKSUM(NEWID())%100) i ,ABS(CHECKSUM(NEWID())%1000) i  from  master.dbo.spt_values v,master.dbo.spt_values v2 
 

SET STATISTICS IO on
SET STATISTICS TIME ON; --время парсинга, компиляции, исполнения

--cost 714, log read 13215, cpu 6682 ms.
select top 1 with ties i, j from t as s1
ORDER BY RANK() OVER(partition by i order by j desc)

--cost 379, log read 13215, cpu 5254
WITH CTE AS(SELECT N=RANK()OVER(PARTITION BY i ORDER BY j DESC),* FROM t)
SELECT i, j
FROM CTE
WHERE N=1;


Проверил. В обычном случае действительно N=1 быстрее. Но в реальности встречались запросы где top 1 ties был быстрее.

В любом случае [Руслан Дамирович] хотел за все предложенные вариант руки отрубать.
5 июн 17, 16:16    [20540862]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
bideveloper
Member

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

на вашем примере быстрее всего у меня отработал запрос
select  i, j from t as t1
where j in (select max(j) from t as t2 where t2.i = t1.i)
5 июн 17, 17:06    [20541039]     Ответить | Цитировать Сообщить модератору
 Re: Почему Merge выдает такие странные результаты?  [new]
Alew
Member

Откуда:
Сообщений: 9
И объяснили и варианты разные привели и перфоманс обсудили.

Сердечно балогодарю!
6 июн 17, 06:48    [20541937]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить