powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Хитрый (?) запрос
5 сообщений из 5, страница 1 из 1
Хитрый (?) запрос
    #32032560
gena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть список продуктов в двух разных базах, у каждого продукта есть список ингредиентов. Таблицы (словари) ингредиентов совпадают. Надо найти продукты что совпадают по ингредиентов... У меня что-то муторное в голове... Не складывается в запрос...
...
Рейтинг: 0 / 0
Хитрый (?) запрос
    #32032565
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нам тоже сложно что-либо "сложить", не видя структуры таблиц
...
Рейтинг: 0 / 0
Хитрый (?) запрос
    #32032568
gena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ok

Как я сказал БД1 и БД2 подобны

Product
id INT (Primary key)
name VARCHAR(50)

Generic
id INT (Primary key)
name VARCHAR(50)

ProductGenerics
fk_Product INT (Foreign key to Product)
fk_Generic INT (Foreign key to Generic)

Таблица Generic одинакова (replica) для обоих БД

Таблица ProductGenerics строит связь many-to-many между двумя первыми.

Пример:
Инградиенты (из Generic)
- Сахар
- Соль
- Мука

описывают продукт "Китайский хлеб" в БД1 и "Японский хлеб" в БД2. Надо составить запрос что даст это соответствие в результате по всем совпавшим продуктам... Количество инградиентов для каждого продукта может быть от 1 до N
...
Рейтинг: 0 / 0
Хитрый (?) запрос
    #32032584
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня получается приблизительно так(не уверен, что до конца правильно)
Идея в следующем
для каждого Продукта выбрать все возможные пары его Ингридиентов. Для эквивалентных Продуктов количество и содежание этих пар должно быть одинаковым

create table #generic1(id int, name varchar(20))

insert #generic1 values(1, 'sugar')
insert #generic1 values(2, 'salt')
insert #generic1 values(3, 'water')
insert #generic1 values(4, 'flour')
insert #generic1 values(5, 'spice')

create table #product1(id int, name varchar(20))
insert #product1 values(1, 'China')
insert #product1 values(2, 'Russia')
insert #product1 values(3, 'Japan')


create table #product2(id int, name varchar(20))
insert #product2 values(3, 'China')
insert #product2 values(2, 'Russia')
insert #product2 values(1, 'Japan')


create table #productgeneric1(fk_ProductINT int, fk_GenericINT int)

insert #productgeneric1 values(1, 1)
insert #productgeneric1 values(1, 2)
insert #productgeneric1 values(1, 3)
insert #productgeneric1 values(2, 1)
insert #productgeneric1 values(2, 2)
insert #productgeneric1 values(3, 2)
insert #productgeneric1 values(3, 3)


create table #productgeneric2(fk_ProductINT int, fk_GenericINT int)
insert #productgeneric2 values(1, 1)
insert #productgeneric2 values(1, 2)
insert #productgeneric2 values(1, 3)
insert #productgeneric2 values(2, 2)
insert #productgeneric2 values(2, 3)
insert #productgeneric2 values(3, 4)
insert #productgeneric2 values(3, 5)


select distinct a.prod1, b.prod2
from
(select a.fk_productint as prod1, a.fk_genericint as gener1_1,
b.fk_genericint as gener1_2,
(select count(*) from #productgeneric1 c where c.fk_productint = a.fk_productint
and c.fk_genericint <> a.fk_genericint) AS cnt1

from #productgeneric1 a
full outer join #productgeneric1 b
on b.fk_productint = a.fk_productint
and b.fk_genericint <> a.fk_genericint
) AS a

inner join

(select a.fk_productint as prod2, a.fk_genericint as gener2_1,
b.fk_genericint as gener2_2,
(select count(*) from #productgeneric2 c where c.fk_productint = a.fk_productint
and c.fk_genericint <> a.fk_genericint) AS cnt2

from #productgeneric2 a
full outer join #productgeneric2 b
on b.fk_productint = a.fk_productint
and b.fk_genericint <> a.fk_genericint
) AS b
on b.gener2_1 = a.gener1_1 and b.gener2_2 = a.gener1_2
and b.cnt2 = a.cnt1

drop table #generic1
drop table #product1
drop table #product2
drop table #productgeneric1
drop table #productgeneric2
...
Рейтинг: 0 / 0
Хитрый (?) запрос
    #32032592
Можно так еще:

SELECT p1.prod_id AS Table1, p2.prod_id AS Table2
FROM db1..ProductsIngredients p1 INNER JOIN db2..ProductsIngredients p2
ON p1.ing_id=p2.ing_id
GROUP BY p1.prod_id, p2.prod_id
HAVING COUNT (p2.prod_id)=(SELECT COUNT(*) FROM ProductsIngredients p3 WHERE
p3.prod_id=p1.prod_id) AND COUNT (p2.prod_id)=(SELECT COUNT(*) FROM
ProductsIngredients p4 WHERE p4.prod_id=p2.prod_id)
-- AND p1.prod_id<p2.prod_id

Последняя строчка закомментирована, так как предполагается, что у тебя данные в разных базах. Если нужно посмотреть совпадающие пары по одной таблице, то последнюю строчку надо раскомментировать. Опять же можно еще красявость навести на этот запрос или попробовать переписать его другим способом.

Если в целом, то проблема таких задачек в том, что в SQL нет средств сравнения кортежей, то есть групп значений, вот и приходится изголяться всякими COUNT'ами, что, впрочем, тоже работает, если соблюдены отношения в базе.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Хитрый (?) запрос
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]