SQL get Parent, где у детей есть определенные значения

Sardoan спросил: 12 мая 2018 в 04:17 в: sql

Предоставлен Parent с полем id и Child с parent_id и name. Как бы выглядел запрос, чтобы получить все Parents, у которых есть двое детей, одно с именем "Джон" и одно с именем "Майк". Моя проблема заключается в том, что я не могу создать запрос, который возвращает родителей, имеющих обоих детей. Я использовал Where IN ('John', 'Mike'), чтобы получить возвращаемые родителями, у которых также есть один ребенок с именем "Джон" или "Майк". Но я хочу только родителей с обоими детьми.

SELECT * FROM Parent
JOIN Child ON Child.parent_id = Parent.id
WHERE Child.name IN ('John', 'Mike')

Мой вопрос, конечно, более сложный, и это только абстракция для того, чего я хочу достичь. Я имею в виду, что мне сначала нужно присоединиться к дочерним элементам parent_id и сделать что-то с этим, но не знаю.

4 ответа

Есть решение
dfundako ответил: 12 мая 2018 в 04:25

Вы можете сделать два соединения и искать свои записи. Этот пример показывает, что родительский 1 вернется с обоими kiddos, но не с родителем 2, у которого есть только Mike.

DECLARE @parent TABLE (ID INT)
DECLARE @child TABLE (ID INT, parentID INT, name VARCHAR(100))INSERT INTO @parent 
VALUES 
(1),
(2),
(3),
(4),
(5),
(6)INSERT INTO @child (ID, parentID, name)
VALUES 
(1, 1, 'Mike'),
(2, 1, 'John'),
(3, 2, 'Mike'),
(4, 2, 'Bill'),
(5, 3, 'Dave'),
(6, 4, 'Sam')SELECT p.*FROM @parent pINNER JOIN @child c1
    ON c1.parentID = p.id
    AND c1.name = 'Mike'INNER JOIN @child c2
    ON c2.parentID = p.ID
    AND c2.name = 'John'
JoeWilson ответил: 12 мая 2018 в 04:23

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

where parent.id in (select parent_id from child where child.name='John')
and parent.id in (select parent_id from child where child.name='Mike')
Sardoan ответил: 12 мая 2018 в 04:33
Два соединения и два подзаголовка выглядят хорошо. Попробуем оба. Благодарю.
dfundako ответил: 12 мая 2018 в 04:34
@Sardoan Я бы порекомендовал вам проверить план выполнения при реализации обоих и посмотреть, что более эффективно для ваших живых данных на основе чтения и времени выполнения.
David Chan ответил: 12 мая 2018 в 04:26

что-то вроде этого будет работать в postgres, если у вас есть.

SELECT parent_id, SUM(num) FROM (
  SELECT parent_id, 1 as num FROM Child Where name = 'John'
  UNION
  SELECT parent_id, 1 as num FROM Child Where name = 'Mike'
) parents 
GROUP BY parent_id HAVING SUM(num) = 2 
Stephen Crosby ответил: 12 мая 2018 в 04:39
Это потенциально может найти родителя двух детей, которых обоих зовут Джон. Кажется маловероятным, но возможно :)
Sardoan ответил: 12 мая 2018 в 04:56
Не в моем случае имена и parent_id уникальны;)
Sardoan ответил: 12 мая 2018 в 04:40

Итак, добавлено решение с двойным соединением в запрос Ecto и оно прошло мои тесты:)

from c in Child,
join: p in Parent, on: c.parent_id = p.id,
join: cc in Child, on: p.id = cc.parent_id,
where: c.name == ^"John",
where: cc.name == ^"Mike"
select: count(p.id)

Спасибо за идеи и быструю помощь:)