выбрать строки в ситуации один ко многим - PullRequest
1 голос
/ 28 апреля 2009

Я думаю, что застрял в этой конкретной ситуации:

Вот мои столы:

item_table:
id | пункт
1:
2: B
3: C

attr_table:
attr | item_id
1: 1
1: 2
2: 1
2: 3
3: 2
3: 3
Я хотел бы знать, технически возможно ли получить какой-либо элемент, связанный с attr = 1 и 3. Ответ должен быть только «B». Аналогично, если я запрашиваю элемент, связанный с attr = 1 и 2, я должен получить только 'A'.

Дело в том, что attr_table может содержать много строк, и я хочу сделать только один запрос.

Этот вопрос звучит легко, и я очень расстроен, что не могу ответить на него.

Я надеялся, что кто-нибудь умнее сможет мне помочь ...

Ответы [ 5 ]

2 голосов
/ 28 апреля 2009

Пример написан для SQLServer, но запрос также должен работать в mysql.

Ключ - это оператор HAVING COUNT, равный количеству атрибутов, которые должны совпадать. Если атрибуты должны быть (1, 2, 5), вам нужно изменить количество на 3.

DECLARE @item_table TABLE (ID INTEGER PRIMARY KEY, Item CHAR(1))
DECLARE @attr_table TABLE (Attr INTEGER, Item_ID INTEGER)

INSERT INTO @item_table VALUES (1, 'A')
INSERT INTO @item_table VALUES (2, 'B')
INSERT INTO @item_table VALUES (3, 'C')

INSERT INTO @attr_table VALUES (1, 1)
INSERT INTO @attr_table VALUES (1, 2)
INSERT INTO @attr_table VALUES (2, 1)
INSERT INTO @attr_table VALUES (2, 3)
INSERT INTO @attr_table VALUES (3, 2)
INSERT INTO @attr_table VALUES (3, 3)


SELECT Item
FROM @item_table i
     INNER JOIN @attr_table a ON a.Item_ID = i.ID
WHERE a.Attr IN (1, 3)
GROUP BY Item
HAVING COUNT(a.Attr) = 2
1 голос
/ 28 апреля 2009
select * from item_table a 
where exists ( select * from attr_table b 
               where b.item_id = a.id and b.attr = 1)
and exists ( select * from attr_table c 
             where c.item_id = a.id and c.attr = 3);

Обратите внимание, что этот запрос говорит именно то, что говорит ваша спецификация: получите все строки из item_table, где существует хотя бы одна строка из attr_table, у которой есть идентификатор этой строки и указан первый атрибут и где существует хотя бы одна строка из attr_table, в которой указан идентификатор этой строки и указан второй атрибут.

1 голос
/ 28 апреля 2009
   SELECT * From attr_table a, item_table i
   where a.item_id = i.id
   and a.attr = 1
   and a.item_id  in (select item_id from attr_table where  attr = 3);  

Возвращает ли задание одну строку для элемента B.

0 голосов
/ 17 июля 2010

Возможно, это слишком поздно, но я бы предложил использовать пару соединений следующим образом:

select i.item, b.item_id, c.item_id 
from item_table i 
join attr_table b on i.id=b.item_id and b.item_id=1
join attr_table c on i.id=c.item_id and c.item_id=2

Вот как я это делаю.

0 голосов
/ 28 апреля 2009
select distinct item_table.item from item_table, attr_table
where item_table.id = attr_table.item_id
and attr_table.attr = 1 and attr_table.attr = 3;

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

(В целом, я надеюсь, что это более эффективно, но не стоит составлять полный список совпадающих строк).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...