Дан 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 и сделать что-то с этим, но я не знаю.
почему бы не использовать WHERE Child.name = "John" AND WHERE Child.name = "Mike";
@AndreyKaplun Я не думаю, что это правильный синтаксис.
Потому что у ребенка не может быть обоих имен;) Я хочу ANSI SQL, возьму его за основу для построения запроса для Ecto.
@dfundako это будет зависеть от движка базы данных
@AndreyKaplun Какой движок БД позволяет 'WHERE condition AND WHERE condition2'?
Сервер MySQL @dfundako
@AndreyKaplun Я могу заверить вас, что SQL Server не позволяет вам ставить WHERE condition1 И WHERE condition2. Второе ключевое слово WHERE вызывает ошибку. И, как заметил Сардоан, имя не может одновременно иметь два разных значения.
он может попробовать @dfundako


Попробуйте указать два шага в предложении 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 Я бы порекомендовал вам проверить план выполнения при реализации обоих и посмотреть, какой из них более эффективен для ваших живых данных на основе чтения и времени выполнения.
Вы можете выполнить два соединения и найти свои конкретные записи. Этот пример показывает, что родитель 1 вернется с обоими детьми, но не родитель 2, у которого есть только Майк.
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 p
INNER 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'
что-то вроде этого будет работать в 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
Это потенциально может найти родителя двух детей, обоих по имени Джон. Вроде маловероятно, но возможно :)
Так, добавил решение с двойным соединением в запрос 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)
Спасибо за идеи и быструю помощь :)
Укажите ядро базы данных, с которым вы работаете, например SQL Server, MySQL и т. д.