Хитрый запрос хелп

tual
Дата: 07.06.2011 00:57:31
Есть исходная таблица о человеке, вида
ID | FatherID | MotherID | Name
где FatherID или MotherID могут быть NULL

данные для таблицы (пример)
1 - NULL - NULL - '1'
2 - 1 - NULL - '2'
3 - NULL - NULL - '3'
4 - 1 - 3 - '4'
5 - 2 - 3 - '5'
6 - 1 - 3 - '6'
7 - 5 - 6 - '7'
8 - 7 - 3 - '8'
Ну то есть мы заполнили всех родственников с их связями )

Вопрос: найти человека с наибольшим количеством партнеров.
Ну то есть по примеру, это получится ID = 3, ибо у нее партнеры 1,2,7

У меня есть еще вопросы, с другими вопросами по сей таблице, но спрошу если уж с ними не разберусь
С этим проломал голову полдня, никакого просвета.
Спасибо.
Ivan Durak
Дата: 07.06.2011 01:09:07
tual
Есть исходная таблица о человеке, вида
ID | FatherID | MotherID | Name
где FatherID или MotherID могут быть NULL

данные для таблицы (пример)
1 - NULL - NULL - '1'
2 - 1 - NULL - '2'
3 - NULL - NULL - '3'
4 - 1 - 3 - '4'
5 - 2 - 3 - '5'
6 - 1 - 3 - '6'
7 - 5 - 6 - '7'
8 - 7 - 3 - '8'
Ну то есть мы заполнили всех родственников с их связями )

Вопрос: найти человека с наибольшим количеством партнеров.
Ну то есть по примеру, это получится ID = 3, ибо у нее партнеры 1,2,7

У меня есть еще вопросы, с другими вопросами по сей таблице, но спрошу если уж с ними не разберусь
С этим проломал голову полдня, никакого просвета.
Спасибо.

select top 1 MID, cnt from
(
select FatherID as MID, count(MotherID) as cnt from table
union
MotherID, count (FatherID) from table
) grp
order by cnt desc
Ivan Durak
Дата: 07.06.2011 01:14:30
ну group by дописать забыл....
tual
Дата: 07.06.2011 01:19:22
Большое спасибо, я его приукрасил для полноты результата :)

select top 1 MID as ID, cnt as RelCount, zz.Name from
	(
		select ID_FATHER as MID, count(ID_MOTHER) as cnt from Person 
		where ID_FATHER is not null and ID_MOTHER is not null
		group by ID_FATHER
		union
		select ID_MOTHER, count(ID_FATHER) from Person 
		where ID_FATHER is not null and ID_MOTHER is not null
		group by ID_MOTHER
	) grp
	join Person zz on zz.ID = MID
	order by cnt desc 

И вроде тоже думал делать через union, пробовал, но я далеко не силен в TSQL

Вообщем, у меня еще есть вопросы, по другим пунктам, но спрошу если сам не осилю
Ivan Durak
Дата: 07.06.2011 09:55:37
автор
where ID_FATHER is not null and ID_MOTHER is not null

это не нужно совсем.... каунт нулы не считает
korneyr
Дата: 07.06.2011 10:23:31
tual,

Мне кажется, вы забыли про маленькую деталь DISTINCT в COUNT-ах,
без них у "3" - 4 RelCount (насколько я понял вы считаете уникальных партнеров,
а у вас на выходе может просто получиться многодетная пара)
declare @Person Table(ID int,ID_FATHER int, ID_MOTHER int,Name varchar(20))
insert @Person values (1,NULL,NULL,'1'),
(2,1,NULL,'2'),
(3,NULL,NULL,'3'),
(4,1,3,'4'),
(5,2,3,'5'),
(6,1,3,'6'),
(7,5,6,'7'),
(8,7,3,'8')

select top 1 MID as ID, cnt as RelCount, zz.Name from
	(
		select ID_FATHER as MID, count(DISTINCT ID_MOTHER) as cnt from @Person 
		where ID_FATHER is not null and ID_MOTHER is not null
		group by ID_FATHER
		union
		select ID_MOTHER, count(DISTINCT ID_FATHER) from @Person 
		where ID_FATHER is not null and ID_MOTHER is not null
		group by ID_MOTHER
	) grp
	join @Person zz on zz.ID = MID
	order by cnt desc 

tual
Дата: 07.06.2011 10:39:10
Я не то чтобы забыл :)
Я про него помнил, потом забыл, потом перед сном вспомнил, потом опять забыл, и вот после напоминания сейчас впишу :)
korneyr
Дата: 07.06.2011 10:41:48
Ivan Durak,

Ага, вы конечно правы
Добавил немного данных чтобы было понятна проблема с DISTINCT (точнее без него)
declare @Person Table(ID int,ID_FATHER int, ID_MOTHER int,Name varchar(20))
insert @Person values (1,NULL,NULL,'1'),
(2,1,NULL,'2'),
(3,NULL,NULL,'3'),
(4,1,3,'4'),
(5,2,3,'5'),
(6,1,3,'6'),
(7,5,6,'7'),
(8,5,3,'8'),
(9,5,6,'9'),
(10,5,6,'10'),
(11,5,6,'11'),
(12,5,6,'12')

select top 1 MID as ID, cnt as RelCount, zz.Name from
	(
		select ID_FATHER as MID, count(DISTINCT ID_MOTHER) as cnt from @Person 
		group by ID_FATHER
		union
		select ID_MOTHER, count(DISTINCT ID_FATHER) from @Person 
		group by ID_MOTHER
	) grp
	join @Person zz on zz.ID = MID
	order by cnt desc 

korneyr
Дата: 07.06.2011 10:45:01
tual,

Это вы молодец, перед сном лучше про все забывать, что бы спалось лучше:)
tual
Дата: 07.06.2011 14:41:53
Ну что ж, продолжу, ибо нифига в голову не лезет
В исходной таблице добавляется еще колонка BirthDate - дата рождения
А задание состоит в том, чтобы найти двух (братьев/сестер/сводных), то есть у них или общий отец, или общая мать.
У этих двоих, должна быть максимальная разница в возрасте.

Максимум до чего додумался, это выбрать детей с одинаковым родителем (и чтоб детей было не меньше 2)

select ID, BirthDate, id_mother as ParentID from Person p
				where id_mother is not null and id_mother in
				(
					select ID_MOTHER from Person p2
					group by ID_MOTHER
					having count(*) > 1
				);

Аналогичный скрипт для id_father