2016-11-01 2 views
0

У меня есть таблица вроде этого:SQL - Присоединение таблицы над собой, чтобы найти людей с такими же родителями

*Id, Name, Surname, Father Name, Mother Name 
--------------------------------------------- 
*1, John, Green, James, Sue 
*2, Michael, Sloan, Barry, Lilly 
*3, Sally, Green, Andrew, Molly 
*4, Michael, Sloan, Barry, Lilly 
*5, Ned, White, James, Sue 

Я хочу, чтобы запрос, который выбирает строки с тем же именем отца и имя матери для заданных имен. Для примера таблицы, когда я хочу, чтобы выбрать Джонсу и Neds с теми же родителями, запрос должен возвращать

1, John, Green, James, Sue 
5, Ned, White, James, Sue 

Я попытался присоединиться стол с самим собой, но независимо от того, как я изменить критерии, где он вернулся декартово произведение. Какие-нибудь советы?

+0

Пожалуйста, помечать вопрос с базой данных, которую вы используете. –

+0

что вы пробовали до сих пор –

+0

Не ясно. Что вы хотите получить, если в дополнение к этому у вас есть следующие 3 строки: '6 Ned, Blue, Roger, Lucy --- 7, John, Black, Roger, Lucy --- 8, Ned, Orange, Ben, Still' –

ответ

0

Используйте подзапрос

SELECT * FROM Table 
WHERE (FatherName, MotherName) IN 
(SELECT FatherName, MotherName FROM Table WHERE Name='John') 
0

Что вам нужно, это называется реляционная разделение. Однако в вашем случае это немного сложнее, поскольку он обычно возвращает агрегированные данные, и вам нужны все строки из таблицы. Так, действительно, автообъединение требуется:

select t.* 
from dbo.Table t 
    inner join (
    select d.FatherName, d.MotherName 
    from dbo.Table d 
    group by d.FatherName, d.MotherName 
    having count(*) > 1 
) sq on sq.FatherName = t.FatherName 
    and sq.MotherName = t.MotherName; 

В подзапросе, вы выбираете только Father+Mother комбинации, которые имеют более чем на 1 запись в таблице, а затем присоединиться к нему с таблицей снова выводить все из этих родителей пары.

0

Self-join - соответствующий метод в этом случае.

SELECT DISTINCT t1.* 
FROM MyTable AS t1 
INNER JOIN MyTable AS t2 
    ON t1.FatherName=t2.FatherName 
    AND t1.MotherName=t2.MotherName 
    AND t1.Id<>t2.Id 
WHERE t1.Name in ('John', 'Ned') 
+0

Если у одних и тех же родителей есть 3 ребенка, все три строки будут дублироваться на выходе. –

+0

Вы правы, «отличный» должен сделать его лучше. – alreadythere

0

Вы можете попробовать это (без group by и count(*))

with fm as 
(select fathername, mothername,row_number() over (partition by fathername,  
mothername order by id) rownum 
from #tmp1 
) 
select b.* 
from #tmp1 b 
join fm 
on b.fathername = fm.fathername 
and b.mothername = fm.mothername 
where fm.rownum = 2