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

Откуда: Краснодар
Сообщений: 55
Существует временная таблица:
CREATE TABLE [##TempProduct] (
[ArtNo]                NVARCHAR (100) NOT NULL,
[sku]                   NVARCHAR(100) NOT NULL,
[producer]           NVARCHAR(100) NOT NULL,
[name]                NVARCHAR(255) NOT NULL
.....

В которой не уникальны значения ArtNo.

Существует основная таблица Product:
CREATE TABLE [Catalog].[Product] (
    [ProductId]             INT            IDENTITY (1, 1) NOT NULL,
    [ArtNo]                 NVARCHAR (100) NOT NULL,
    [Article]                NVARCHAR (100) NOT NULL,
    [Name]                  NVARCHAR (255) NOT NULL,
......
CREATE UNIQUE NONCLUSTERED INDEX [IX_Product]
    ON [Catalog].[Product]([ArtNo] ASC) WITH (FILLFACTOR = 80);


В которой ArtNo уникален.

При вставке из ##TempProduct в Product с помощью Merge уникальность ArtNo не проверяется и соответственно, при наличии дубликатов происходит ошибка:
MERGE Catalog.Product AS target
	USING (SELECT ArtNo, sku, name FROM ##TempProduct) 	AS source
	ON (target.ArtNo = source.ArtNo)
	WHEN MATCHED THEN
		UPDATE SET target.[DateModified] = SYSDATETIME()
	WHEN NOT MATCHED THEN
		INSERT ([ArtNo],[Article],[Name]) 
		VALUES (source.ArtNo,source.sku,source.[Name]);


Мне нужно, чтобы при наличии нескольких дублирующихся записей в TempTable происходило обновление одной, первоначально созданной, а не ее обновление.

Решал эту задачу курсором. Работает, но очень медленно. 1000 строк/сек. А объемы данных - до миллиона записей

Количество столбцов в таблицах в примере сократил..
7 сен 15, 00:44    [18116658]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37068
Ну так обеспечьте в using уникальность ArtNo.
7 сен 15, 00:51    [18116667]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
Artprog
Member

Откуда: Краснодар
Сообщений: 55
Гавриленко Сергей Алексеевич
Ну так обеспечьте в using уникальность ArtNo.


Не силен в Sql.. Пробовал Через DISTINCT и GOUP BY - не получилось, т.к. они группируют по всем выбираемым полям.. Прошу помочь составить запрос.
7 сен 15, 01:16    [18116698]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37068
Artprog
Гавриленко Сергей Алексеевич
Ну так обеспечьте в using уникальность ArtNo.


Не силен в Sql.. Пробовал Через DISTINCT и GOUP BY - не получилось, т.к. они группируют по всем выбираемым полям.. Прошу помочь составить запрос.
Напишите GROUP BY по _одному_ полю.
7 сен 15, 02:16    [18116743]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
aleks2
Guest
;with
rawsource as (SELECT ArtNo, sku, name, row_number() over(prtition by ArtNo order by <!!!тут обеспечьте порядок "создания">) as n FROM ##TempProduct)

, source as (SELECT ArtNo, sku, name FROM rawsource where n = 1)

MERGE Catalog.Product AS target
	USING source
	ON (target.ArtNo = source.ArtNo)
	WHEN MATCHED THEN
		UPDATE SET target.[DateModified] = SYSDATETIME()
	WHEN NOT MATCHED THEN
		INSERT ([ArtNo],[Article],[Name]) 
		VALUES (source.ArtNo,source.sku,source.[Name]);
7 сен 15, 07:36    [18116811]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
Artprog
Member

Откуда: Краснодар
Сообщений: 55
[quot Напишите GROUP BY по _одному_ полю.[/quot]
Но тогда я бы не смог добавить в выборку остальные поля..
7 сен 15, 10:52    [18117344]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
Artprog
Member

Откуда: Краснодар
Сообщений: 55
aleks2
;with
rawsource as (SELECT ArtNo, sku, name, row_number() over(prtition by ArtNo order by <!!!тут обеспечьте порядок "создания">) as n FROM ##TempProduct)
, source as (SELECT ArtNo, sku, name FROM rawsource where n = 1)


Большое спасибо, Ваш код работает как нужно. Осталось решить еще одну пролему.
После добавления в Product необходимо добавить значения в таблицу Offers (товарные предложения). Только тут нужно загрузить все товарные предложения, но, добавляя суффикс к ArtNo.

т.е. Если в TempProduct есть три товарных предложения на один товар:
ArtNo Name Amount Price
C110 Лампочка 2 500
C110 Лампочка 5 800
C110 Лампочка 3 589
В Product товар не должен задвоиться (РЕШЕНО), а в Offer должно вставиться:
C110 2 500
C110_1 5 800
C110_2 3 589

Вот код, вставляющий в Offer:
;with
rawsource as (SELECT ArtNo, sku, name, price, purchaseprice, amount, producer, [uid] 
, row_number() over(partition by ArtNo order by ArtNo) as n FROM ##TempProduct)
, source as (SELECT ArtNo, sku, name, price,  purchaseprice, amount, producer, [uid]
 FROM rawsource where n = 1)

		MERGE Catalog.Offer AS target
		USING source
		ON (target.ArtNo = source.ArtNo + '-' + CAST(@VendorId AS VARCHAR))
		WHEN MATCHED THEN
			UPDATE  SET 
target.[Article] = source.[sku], target.[Price] = source.price, target.[SupplyPrice] = source.purchaseprice
		WHEN NOT MATCHED THEN
		INSERT ([ProductID],[VendorID],[ArtNo],[Article],[Price],[SupplyPrice],[Amount],[Main],[PeriodFrom],[PeriodTo],[ProductName],[BrandName],[Information])
		VALUES ((SELECT TOP 1 ProductId FROM Catalog.Product WHERE ArtNo = source.ArtNo),
	@VendorId, source.ArtNo ,source.sku,source.price,source.purchaseprice,source.amount);
7 сен 15, 12:12    [18117845]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
aleks2
Guest
;with
rawsource as (SELECT ArtNo, sku, name, price, purchaseprice, amount, producer, [uid], row_number() over(partition by ArtNo order by ArtNo) as n FROM ##TempProduct)
, source as (SELECT ArtNo+'_'+cast(n as varchar(16)) as ArtNo, sku, name, price,  purchaseprice, amount, producer, [uid] FROM rawsource)

		MERGE Catalog.Offer AS target
		USING source
		ON (target.ArtNo = source.ArtNo + '-' + CAST(@VendorId AS VARCHAR))
		WHEN MATCHED THEN
			UPDATE  SET 
target.[Article] = source.[sku], target.[Price] = source.price, target.[SupplyPrice] = source.purchaseprice
		WHEN NOT MATCHED THEN
		INSERT ([ProductID],[VendorID],[ArtNo],[Article],[Price],[SupplyPrice],[Amount],[Main],[PeriodFrom],[PeriodTo],[ProductName],[BrandName],[Information])
		VALUES ((SELECT TOP 1 ProductId FROM Catalog.Product WHERE ArtNo = source.ArtNo),
	@VendorId, source.ArtNo ,source.sku,source.price,source.purchaseprice,source.amount);
7 сен 15, 13:46    [18118456]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
Artprog
Member

Откуда: Краснодар
Сообщений: 55
aleks2,

Этим запросом артикулы создаются правильно, а цена и остаток пишется одинаковая для всех предложений..
7 сен 15, 19:02    [18120464]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
aleks2
Guest
Artprog
aleks2,

Этим запросом артикулы создаются правильно, а цена и остаток пишется одинаковая для всех предложений..


Ну дык, поправь. Я по фотографии не лечу.
7 сен 15, 19:37    [18120507]     Ответить | Цитировать Сообщить модератору
 Re: Merge и проверка на дубли  [new]
Artprog
Member

Откуда: Краснодар
Сообщений: 55
aleks2
Artprog
aleks2,

Этим запросом артикулы создаются правильно, а цена и остаток пишется одинаковая для всех предложений..


Ну дык, поправь. Я по фотографии не лечу.


Я разобрался в запросе, написанном вами, нашел свою ошибку. Большое спасибо за помощь - все работает и получил ценные знания)
7 сен 15, 22:37    [18121004]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить