Выберите родителей, чтобы получить список интересных свойств в дочерних элементах родителя.

Я боролся с заголовком, но позвольте мне объяснить:

Допустим, у меня есть две структуры данных: Parent и Child. В моем (Scala) коде каждый экземпляр Parent имеет список Child. В базе данных у меня есть две таблицы, одна для Parent и одна для Child. Каждая запись в таблице Child имеет значение parentId, указывающее на ее Parent.

Таблица для Parent: id int
Таблица для Child: id int, parentId int (внешний ключ parent.id)

Имея список Child идентификаторов, я хочу выбрать каждый Parent (которых может быть ни один, один или несколько), у которого есть все эти дочерние элементы. Может ли кто-нибудь помочь мне с запросом?

ОБНОВИТЬ:

Мой пример не охватывает мой вариант использования - извините. Мне нужно добавить еще одно поле в Child: назовем его interestingThing. Вот таблицы:

CREATE TABLE Parent (
  id                INT PRIMARY KEY
);
CREATE TABLE Child (
  id                INT PRIMARY KEY,
  interestingThing  INT,
  parentId          INT,
  FOREIGN KEY (parentId) REFERENCES Parent (id)
);

Что мне нужно, так это найти родителей, у которых есть дети, с моим списком интересных вещей. Учитывая эти данные:

INSERT INTO Parent VALUES (1);
INSERT INTO Parent VALUES (2);

INSERT INTO Child VALUES (1, 42, 1);
INSERT INTO Child VALUES (2, 43, 1);
INSERT INTO Child VALUES (3, 44, 1);
INSERT INTO Child VALUES (4, 8, 2);
INSERT INTO Child VALUES (5, 9, 2);
INSERT INTO Child VALUES (6, 10, 2);
INSERT INTO Child VALUES (7, 8, 1);

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

  • Учитывая интересные вещи (42, 43), я хотел бы найти родителя с id 1.
  • Учитывая интересные вещи (43, 44), я хотел бы найти родителя с id 1.
  • Учитывая интересные вещи (8), я хотел бы найти родителя с идентификатором 1 и родителя с идентификатором 2.
  • Учитывая интересности (8, 10), хотелось бы найти родителя с id 2.

person L42    schedule 12.04.2017    source источник
comment
Добавьте несколько образцов данных таблицы и ожидаемый результат, а также отформатированный текст. Также покажите нам вашу текущую попытку запроса. И пометьте СУБД, которые вы используете.   -  person jarlh    schedule 12.04.2017
comment
Спасибо. Сделаю.   -  person L42    schedule 12.04.2017


Ответы (2)


Вы можете использовать функцию ARRAY_AGG, чтобы получить массив всех interestingThing для parent.id и использовать оператор @> (содержит):

SELECT p.id 
FROM parent p 
INNER JOIN child c 
  ON p.id = c.parentId
GROUP BY p.id 
HAVING ARRAY_AGG(interestingThing) @> '{8}';

┌────┐
│ id │
├────┤
│  1 │
│  2 │
└────┘
(2 rows)

SELECT p.id 
FROM parent p 
INNER JOIN child c 
  ON p.id = c.parentId
GROUP BY p.id 
HAVING ARRAY_AGG(interestingThing) @> '{8,10}';

┌────┐
│ id │
├────┤
│  2 │
└────┘
(1 row)
person Marth    schedule 12.04.2017
comment
Фантастика! Спасибо :) - person L42; 12.04.2017

Вы можете сделать это с чем-то вроде этого

select  parentId
from    Child
where   id in ( /* your list */ )
group by parentId
having  count(distinct id) = /* your list's length */

Вы получите только родителей, у которых количество детей равно длине вашего списка, только с учетом желаемых детей и каждого только один раз.

person Stefano Zanini    schedule 12.04.2017
comment
Спасибо за ответ! Вы имеете в виду where parentId in (my list) здесь? Кроме того, как я могу изменить это, чтобы родитель мог иметь больше детей, которых нет в моем списке? - person L42; 12.04.2017
comment
Нет, я имею в виду то, что я написал :) Я подумаю над решением описанного вами изменения - person Stefano Zanini; 12.04.2017
comment
Спасибо. См. мой обновленный вопрос - мой первый вопрос не охватывал мой вариант использования. - person L42; 12.04.2017