Подскажите пож как решить такую задачку

leapold
Дата: 12.02.2013 00:18:09
Highschooler ( ID, name, grade )
English: There is a high school student with unique ID and a given first name in a certain grade.

Friend ( ID1, ID2 )
English: The student with ID1 is friends with the student with ID2. Friendship is mutual, so if (123, 456) is in the Friend table, so is (456, 123).

Likes ( ID1, ID2 )
English: The student with ID1 likes the student with ID2. Liking someone is not necessarily mutual, so if (123, 456) is in the Likes table, there is no guarantee that (456, 123) is also present.

__________________________________
For all cases where A is friends with B, and B is friends with C, add a new friendship for the pair A and C. Do not add duplicate friendships, friendships that already exist, or friendships with oneself.
_____________________________________
Гавриленко Сергей Алексеевич
Дата: 12.02.2013 00:24:56
Тестовые задания нужно решать самостоятельно.
leapold
Дата: 12.02.2013 00:27:44
Уже голову сломал на нем .Весь день хожу вокруг до около
aleks2
Дата: 12.02.2013 05:51:29
declare @Friend table( ID1 int, ID2 int ) 

insert @Friend
select 2, 1
union all
select 2, 3
union all
select 4, 1
union all
select 5, 6


-- 1. Приводим @Friend к ID1 < ID2 

update @Friend set id1 = id2
                  ,id2 = id1
where id1>id2;

select * from @friend;

-- 2. ваяем пары
;with
-- все пары "A is friends with B, and B is friends with C, add a new friendship for the pair A and C"
--, за вычетом "friendships with oneself"
allpairs as (
	select F1.id2 as id1, F2.id2 as id2
	from @Friend F1 inner join @Friend F2 on F1.id1=F2.id1
	where F1.id2 <> F2.id2 
	union
	select F1.id2 as id1, F2.id1 as id2
	from @Friend F1 inner join @Friend F2 on F1.id1=F2.id2
	where F1.id2 <> F2.id1 
	union
	select F1.id1 as id1, F2.id2 as id2
	from @Friend F1 inner join @Friend F2 on F1.id2=F2.id1
	where F1.id1 <> F2.id2 
	union
	select F1.id1 as id1, F2.id1 as id2
	from @Friend F1 inner join @Friend F2 on F1.id2=F2.id2
	where F1.id1 <> F2.id1 
)
--select * from allpairs;
,
-- нормализованные пары, "id1 < id2" без повторов
normalpairs as
(select distinct
        (select min(id1) from (select id1 union all select id2) X) as id1
      , (select max(id1) from (select id1 union all select id2) X) as id2
   from allpairs)
--select * from normalpairs;
,
-- не существующие пары
nonexistingpairs as
( select * from normalpairs
  except
  select * from @Friend
)
-- ну и фсе
insert @Friend
select * from nonexistingpairs;

select * from @friend;
Ennor Tiegael
Дата: 12.02.2013 06:17:24
Гавриленко Сергей Алексеевич,

Прикол декларативных языков в том, что на самом деле написать решение можно :). Другой вопрос, что решение, которое ТС не смог сам написать, он вряд ли сможет понять, не говоря уже о том, чтобы его объяснить другим. Тут-то его за жабры и возьмут
leapold
Дата: 12.02.2013 10:13:26
Спасибо за ответ.
Решение правильное но очень сложное.
Я уверен что можно сделать легче.
Сижу копаю дальше
Ennor Tiegael
Дата: 12.02.2013 10:30:54
leapold,

Решение неправильное, т.к. оно основывается на неправильно понятом условии. aleks2 счел, что зеркальные записи (id2, id1) в таблице Friend отсутствуют, в то время как в условии явно сказано иное:
автор
Friendship is mutual, so if (123, 456) is in the Friend table, so is (456, 123)
Хотя я не исключаю, что оно будет работать на правильных данных.
Cygapb-007
Дата: 12.02.2013 10:40:56
требуется ли по постановке задачи из цепочек (1,2)(2,4)(4,6) и (1,3)(3,5)(5,7) выводить (6,7)? Или только ближайших друзей?
aleks2
Дата: 12.02.2013 10:41:28
leapold
Спасибо за ответ.
Решение правильное но очень сложное.
Я уверен что можно сделать легче.
Сижу копаю дальше

Копай, копай.

Ennor Tiegael
leapold,
Решение неправильное, т.к. оно основывается на неправильно понятом условии. aleks2 счел, что зеркальные записи (id2, id1) в таблице Friend отсутствуют, в то время как в условии явно сказано иное:
автор
Friendship is mutual, so if (123, 456) is in the Friend table, so is (456, 123)
Хотя я не исключаю, что оно будет работать на правильных данных.

Это просто условие неправильное. Надо перепроектировать данные.
invm
Дата: 12.02.2013 10:47:47
declare @f table(id1 int, id2 int, primary key (id1, id2));

insert into @f
values
 (1, 2), (2, 1), (1, 3), (3, 1), (2, 3), (3, 2), (3, 4), (4, 3), (4, 5), (5, 4);

insert into @f
select distinct
  a.id1, c.id1
from
 @f a join
 @f b on b.id1 = a.id2 join
 @f c on c.id1 = b.id2
where
 a.id1 <> c.id1 and
 not exists(select 1 from @f where id1 = a.id1 and id2 = c.id1);

select * from @f;