Quantcast
Channel: SQL.ru: Microsoft SQL Server
Viewing all articles
Browse latest Browse all 7251

Декартово произведение, как избавиться

$
0
0
Здравствуйте. Вот и мне пришлось обратиться за помощью. Есть три таблицы:

GraphicGroups
graphicgroup_id [int] PK graphicgroup_name [nvarchar]

GraphicGroupLinks
graphicgrouplink_id [int] PK graphicgroup_id [int] graphic_id [int] position [int]

Graphics
graphic_id [int] PK graphic_code [nvarchar]


Задача состоит в том, чтобы создать копию группы, создать копию графиков из группы оригинала и засунуть копии графиков в копию группы.
Если на примере, то есть группа 1. В нее входят графики a b c. На выходе должна создаться группа 1 (С) и в нее должны входить графики а (С), b (C), c (C).

Копию группы я создал. Копию графиков тоже.

declare @GG nvarchar(250) 
set @GG = '1234' -- graphicgroup_name нужной группы
declare @A int

BEGIN TRAN
INSERT INTO GraphicGroups -- копирование группы
(graphicgroup_name, parent_id)
	   SELECT	 @GG + ' (C)',
			 parent_id,
	   FROM GraphicGroups
	   WHERE graphicgroup_name = @GG
	   select @A = MAX(graphicgroup_id) from GraphicGroups


INSERT INTO Graphics --копирование графиков, входящих в группу у которой название @GG
(graphic_code)
SELECT graphic_code + ' (C)'
FROM Graphics g join GraphicGroupLinks ggl 
on g.graphic_id = ggl.graphic_id
join GraphicGroups gg
on ggl.graphicgroup_id = gg.graphicgroup_id 
and graphicgroup_name = @GG

Все круто, все получилось.
Однако теперь их нужно связать в третьей таблице. и вот тут загвоздка. У меня на выходе получается декартово произведение graphic_id и position (позиция графика в группе), то есть создается вместо 3 записей graphicgrouplink_id аж 9. Естественно, исходных данных на деле больше.

INSERT INTO GraphicGroupLinks
(graphicgroup_id, graphic_id, position)
	   SELECT	 @A, --выбор скопированой группы
			 g.graphic_id,
			 ggl.position
	   FROM Graphics g join GraphicGroupLinks ggl 
	   on g.graphic_id not in (select graphic_id from GraphicGroupLinks) -- выбор скопированных графиков
	   and graphic_code LIKE '% (C)' -- уточнение, копия или нет
	   join GraphicGroups gg  
	   on ggl.graphicgroup_id = gg.graphicgroup_id -- получение позиций на основе оригинальной группы
	   and graphicgroup_name = @GG
           order by g.graphic_id


Вопрос вот в чем - как избавиться от этого декартова произведения? Какую связь я пропустил? Причем, если я в GraphicGroupLinks буду пихать не копии графиков а оригиналы - он покажет 3 строки, как и нужно. то есть получится
graphic_id position
a1
b2
c3

мне нужно получить тоже самое для копий
graphic_id position
a (С)1
b (С)2
c (С)3

а то пока получается только такой вывод
graphic_id position
a (С)1
a (С)2
a (С)3
b (С)1
b (С)2
b (С)3
c (С)1
c (С)2
c (С)3

Viewing all articles
Browse latest Browse all 7251

Trending Articles