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

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

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
22 авг 17, 16:34    [20741904]     Ответить | Цитировать Сообщить модератору
 Re: Декартово произведение, как избавиться  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3464
Какой селект такой и результат
22 авг 17, 17:48    [20742112]     Ответить | Цитировать Сообщить модератору
 Re: Декартово произведение, как избавиться  [new]
Serп
Member

Откуда:
Сообщений: 17
getred,
@A по идее правильнее инициализировать через:
select @A = @@IDENTITY

А вообще, один график может принадлежать разным группам?
Если нет, то проще добавить поле graphicgrouplink_id в Graphics, а если да, то почему бы в копию группы не воткнуть оригинальные графики, зачем делать их копии?
22 авг 17, 17:50    [20742118]     Ответить | Цитировать Сообщить модератору
 Re: Декартово произведение, как избавиться  [new]
getred
Member

Откуда:
Сообщений: 8
Ролг Хупин,

Что конкретно в селекте не то? (
22 авг 17, 17:51    [20742126]     Ответить | Цитировать Сообщить модератору
 Re: Декартово произведение, как избавиться  [new]
Шыфл
Member

Откуда: Прага
Сообщений: 774
getred
Ролг Хупин,
Что конкретно в селекте не то? (

FROM Graphics g join GraphicGroupLinks ggl 
	   on g.graphic_id not in (select graphic_id from GraphicGroupLinks) -- выбор скопированных графиков
	   and graphic_code LIKE '% (C)'


Это оно так работает? тут нет ключей, я думаю на выходе получается декартово произведение...
22 авг 17, 17:55    [20742142]     Ответить | Цитировать Сообщить модератору
 Re: Декартово произведение, как избавиться  [new]
getred
Member

Откуда:
Сообщений: 8
Serп,

Хм, с переменной А попробую завтра. Почему так? Я вторую неделю только в этом (
График может принадлежать разным группам.
Обьясню почему не оригиналы - копии создаются для тестирования чего-либо, каких либо операций с ними, если операции успешны то пишется в оригинал.
Я не знаю почему так усложнено это, ибо вообще можно быдо в графикс засунуть группу и не париться. Но увы, что имеется то и приходится использовать.
22 авг 17, 17:59    [20742164]     Ответить | Цитировать Сообщить модератору
 Re: Декартово произведение, как избавиться  [new]
getred
Member

Откуда:
Сообщений: 8
Шыфл,

Ключи есть. Они создались во втором инсерте. Соглашусь, что я вызываю коряво, но я не нашел путей как, допустим, пятидесяти графикам присвоить записи в graphgrouplinks. Я не могу знать их id когда они создались. Я могу их записать только таким образом. Если есть другой способ - я жадно его прочитаю и осмыслю.
22 авг 17, 18:04    [20742183]     Ответить | Цитировать Сообщить модератору
 Re: Декартово произведение, как избавиться  [new]
dao
Member

Откуда: Москва
Сообщений: 771
getred
Шыфл,

Ключи есть. Они создались во втором инсерте. Соглашусь, что я вызываю коряво, но я не нашел путей как, допустим, пятидесяти графикам присвоить записи в graphgrouplinks. Я не могу знать их id когда они создались. Я могу их записать только таким образом. Если есть другой способ - я жадно его прочитаю и осмыслю.

если правильно понял - то читайте про output при инсерте
23 авг 17, 15:36    [20744543]     Ответить | Цитировать Сообщить модератору
 Re: Декартово произведение, как избавиться  [new]
getred
Member

Откуда:
Сообщений: 8
Решение проблемы - нужно было всего-лишь взять еще одну таблицу графикс и взять одну связь.
24 авг 17, 14:04    [20747058]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить