2010-04-03 10 views
12

Tôi có mối quan hệ một-nhiều đơn giản. Tôi muốn chọn các hàng từ phụ huynh chỉ khi họ có ít nhất một đứa con. Vì vậy, nếu không có con, thì hàng cha mẹ không được trả về trong tập kết quả.Làm cách nào để chọn hàng chính chỉ khi có ít nhất một con?

Ví dụ:

Parent: 
+--+---------+ 
|id| text | 
+--+---------+ 
| 1| Blah | 
| 2| Blah2 | 
| 3| Blah3 | 
+--+---------+ 

Children 
+--+------+-------+ 
|id|parent| other | 
+--+------+-------+ 
| 1| 1 | blah | 
| 2| 1 | blah2 | 
| 3| 2 | blah3 | 
+--+------+-------+ 

Tôi muốn các kết quả là:

+----+------+ 
|p.id|p.text| 
+----+------+ 
| 1 | Blah | 
| 2 | Blah2| 
+----+------+ 

Trả lời

15

Bạn có thể làm điều này bằng một EXISTS, như thế này:

SELECT * 
FROM Parent p 
WHERE EXISTS (SELECT 1 
       FROM Chilren c 
       WHERE c.Parent = p.id) 

Hoặc sử dụng một IN như thế này:

SELECT * 
FROM Parent p 
WHERE p.id IN (SELECT c.Parent 
       FROM Chilren c) 
+2

tôi đã không kiểm tra nhưng tôi đoán đây là chậm hơn so với một tham gia. – Hogan

+3

@Hogan - Cách tồn tại của nó là phương pháp nhanh nhất. Trình tối ưu hóa sẽ thực hiện cùng một kế hoạch thực hiện cho một phép nối ngoài được kiểm tra rỗng ... sẽ được ** nhanh chóng, nhưng tồn tại không bao giờ chậm hơn. –

+0

Gọn gàng. Cảm ơn @Nick. Điều này là đúng cho mysql, sql sq và oracle? – Hogan

1
SELECT p.* 
FROM Parent p 
WHERE EXISTS (SELECT 'X' FROM Children c WHERE c.parent = p.id); 
2
Select p.id, p.text 
from Parent p 
inner join Children c on p.id = c.parent 
group by p.id, p.text 
12

Một inner join chỉ trả lại hàng phù hợp cả hai bảng:

select distinct p.* 
from Parent p 
inner join Children c on c.parent = p.id 
+1

đây là, theo ý kiến ​​của tôi, cách đơn giản nhất để thực hiện điều này và phải là câu trả lời được chấp nhận. – adriandz