2013-09-30 3 views
0

Предположим, у меня есть две связанные таблицы parents и children с отношением «один ко многим» (один parent для многих children). Обычно, когда мне нужно обработать информацию об этих таблицах вместе, я сделать запрос, такие как следующие (как правило, с пунктом WHERE добавлен в):В SQL, как я могу выбрать всех родителей, у которых есть дети?

SELECT * FROM parents INNER JOIN children ON (parents.id = children.parent_id); 

Как я могу выбрать все parents, которые имеют по крайней мере один child не теряя времени, соединяя все children с их parents?

Я думал использовать какой-то OUTER JOIN, но я не уверен, что с ним делать.

(Обратите внимание, что я задаю этот вопрос, как правило, так не дают мне ответ, который привязан к конкретной реализации СУБД, если нет общего решения.)

+0

Выполняйте 'LEFT JOIN' и фильтруйте на некотором дочернем поле (например, имя) как' NOT NULL'. Чтобы иметь каждого родителя только один раз, вам нужно будет использовать DISTINCT или (если это имеет смысл), 'GROUP BY'. –

+0

@ PM77-1 Спасибо! Я получил его работу с 'GROUP BY', я не уверен, как использовать DISTINCT. Кроме того, можете ли вы опубликовать это как ответ? – Matt

ответ

2

Как я кладу ранее в комментариях:

Решение с LEFT JOIN и GROUP BY:

SELECT p.parents.id FROM parents p 
LEFT JOIN children c ON (p.parents.id = c.children.parent_id) 
WHERE children.parent_id IS NOT NULL 
GROUP BY p.parents_id 

То же самое с DISTINCT:

SELECT DISTINCT p.parents.id FROM parents p 
LEFT JOIN children c ON (p.parents.id = c.children.parent_id) 
WHERE children.parent_id IS NOT NULL 

Он должен работать в большинстве диалектов SQL, хотя некоторые из них требуют as при назначении table aliases.

Вышеописанное значение не проверено. Надеюсь, я не сделал опечаток.

+0

Нужны ли в этом случае псевдонимы таблицы? – Matt

+0

Не совсем. Вы можете использовать реальные имена таблиц, как в вашем коде. Я просто использовал их, так как кажется чище. –

0

попробовать это

select parent_id,(select count(1) from children where parent_id = x.parent_id) 
from parent x where 
(select count(1) from children where parent_id = x.parent_id) > 0 
+0

Не подзапросы обычно медленные? – Matt

+0

Положите время и сравните. подзапрос просто подсчитывает строки и похож на объединение таблиц. – maSTAShuFu

2

Я думаю, что самое простое решение, которое позволяет избежать JOIN бы:

SELECT * FROM parents WHERE id IN (SELECT parent_id FROM children); 
Смежные вопросы