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

Откуда:
Сообщений: 5
Здравствуйте.

Есть два множества A (элементы A1, A2, A3) и T (элементы T1, T2, T3, T4, T5), см. приложенную картинку. Между элементами множеств есть связи. Все это хранится в БД.

Задача: найти все элементы множества T (хранящееся в БД) которые связаны со всеми элементами множества T' (задается как входной параметр), которое является подмножеством T.

Т.е. между элементами множества T могут существовать связи через элементы множества A.

Если глянуть на приложенную картинку, то там есть два варианта. В обоих вариантах T' = (T1, T3), т.е. нужно найти все элементы T, которые связаны и с T1 и с T2 одновременно, т.е. конъюнкция.

В варианте 1 это будут только сами T1 и T3, т.к. T2 связано только с T3, но не связано с T1.
В варианте 2 это будут T1, T2, T3, т.к., благодаря дополнительной связи между T1 и A2, T2 становится связанным с T1 и T3.

Вот такая вот задача. Используемая БД SQL Server 2005.

Если перейти от абстракции к реалиям жизни, то множество A - это таблица статей, множество T - таблица тегов, есть также третья таблица со связями много-к-много между статьями и тегами. При выборе одного или больше тегов, требуется найти и задизаблить теги, которые не связанны с хотя бы одним из выбранных тегов.

Пока в голову приходит только inner join, потом group by и having count(*) = [кол-во выбранных тегов, т.е. кол-во элементов T'], но считаю этот способ кривоватым.

Буду очень признателен за более оптимальный способ решения задачи.

К сообщению приложен файл. Размер - 0Kb
16 июл 09, 17:12    [7425604]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом на выборку из двух связанных множеств  [new]
так наверна
Guest
Изверг Андреевич
...
Пока в голову приходит только inner join, потом group by и having count(*) = [кол-во выбранных тегов, т.е. кол-во элементов T'], но считаю этот способ кривоватым.
...


да нормальный способ
drop table A
drop table T
drop table A2T

create table A (NumA int)
create table T (NumT int)
create table A2T (NumA int, NumT int)

insert into A
select 1 union all
select 2 union all
select 3
 
insert into T
select 1 union all
select 2 union all
select 3 union all
select 4 union all
select 5

insert into A2T
select 1, 1 union all
select 1, 3 union all
select 2, 2 union all
select 2, 3

--SELECT * FROM A
--SELECT * FROM T
--SELECT * FROM A2T

SELECT T1.NumT Q1, T2.NumT Q2
FROM T T1
INNER JOIN A2T A2T1
  ON T1.NumT = A2T1.NumT
INNER JOIN A
  ON A2T1.NumA = A.NumA
INNER JOIN A2T A2T2
  ON A.NumA = A2T2.NumA
INNER JOIN T T2
  ON A2T2.NumT = T2.NumT
WHERE T1.NumT IN (1, 3)

-- 1.
SELECT a.Q2
FROM (
  SELECT T1.NumT Q1, T2.NumT Q2
  FROM T T1
  INNER JOIN A2T A2T1
    ON T1.NumT = A2T1.NumT
  INNER JOIN A
    ON A2T1.NumA = A.NumA
  INNER JOIN A2T A2T2
    ON A.NumA = A2T2.NumA
  INNER JOIN T T2
    ON A2T2.NumT = T2.NumT
  WHERE T1.NumT IN (1, 3)) a
GROUP BY a.Q2
HAVING COUNT(DISTINCT a.Q1) = 2

DELETE FROM A2T

insert into A2T
select 1, 1 union all
select 1, 3 union all
select 2, 1 union all
select 2, 2 union all
select 2, 3

-- 2.
SELECT a.Q2
FROM (
  SELECT T1.NumT Q1, T2.NumT Q2
  FROM T T1
  INNER JOIN A2T A2T1
    ON T1.NumT = A2T1.NumT
  INNER JOIN A
    ON A2T1.NumA = A.NumA
  INNER JOIN A2T A2T2
    ON A.NumA = A2T2.NumA
  INNER JOIN T T2
    ON A2T2.NumT = T2.NumT
  WHERE T1.NumT IN (1, 3)) a
GROUP BY a.Q2
HAVING COUNT(DISTINCT a.Q1) = 2
16 июл 09, 18:23    [7426017]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом на выборку из двух связанных множеств  [new]
izwerg
Guest
вот, вот. это именно то что мне пришло в голову и я реализовал. но меня почему-то смущает такой подход... "чую бесовщину, а обосновать не могу" (с) не помню кто.

в любом случае, спасибо за ответ. приятно найти единомышленников :)
17 июл 09, 10:23    [7427574]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить