SQL:结合协助同一事件的人

时间:2013-06-08 01:40:19

标签: sql postgresql

create table people(
  id_pers int,
  nom_pers char(25),
  d_nais date,
  d_mort date,
  primary key(id_pers)
);

create table event(
  id_evn int,
  primary key(id_evn)
);

create table assisted_to(
  id_pers int,
  id_evn int,
  foreign key (id_pers) references people(id_pers),
  foreign key (id_evn) references event(id_evn)
);

insert into people(id_pers, nom_pers, d_nais, d_mort) values (1, 'A', current_date - integer '20', current_date);
insert into people(id_pers, nom_pers, d_nais, d_mort) values (2, 'B', current_date - integer '50', current_date - integer '20');
insert into people(id_pers, nom_pers, d_nais, d_mort) values (3, 'C', current_date - integer '25', current_date - integer '20');

insert into event(id_evn) values (1);
insert into event(id_evn) values (2);
insert into event(id_evn) values (3);
insert into event(id_evn) values (4);
insert into event(id_evn) values (5);

insert into assisted_to(id_pers, id_evn) values (1, 5);
insert into assisted_to(id_pers, id_evn) values (2, 5);
insert into assisted_to(id_pers, id_evn) values (2, 4);
insert into assisted_to(id_pers, id_evn) values (3, 5);
insert into assisted_to(id_pers, id_evn) values (3, 4);
insert into assisted_to(id_pers, id_evn) values (3, 3);

我需要找到在任何特定日期协助同一事件的夫妇。

我试过了:

select p1.id_pers, p2.id_pers from people p1, people p2, assisted_event ae
where ae.id_pers = p1.id_pers
and   ae.id_pers = p2.id_pers

但是返回0行。

我做错了什么?

3 个答案:

答案 0 :(得分:2)

试试这个:

 select distint ae.id_evn, 
    p1.nom_pers personA, p2.nom_pers PersonB
 from assieted_to ae
     Join people p1 
        On p1.id_pers = ae.id_pers 
     Join people p2 
        On p2.id_pers = ae.id_pers
           And p2.id_pers > p1.id_pers

这会产生协助同一事件的所有人[夫妻]。使用您的架构,无法将结果限制为他们在同一天协助的情况。假设如果他们协助同一事件,则该事件只能在一天发生。

答案 1 :(得分:2)

您选择了两个人,因此您还需要选择两个assisted_event行,因为每个人在assisted_event表中都有自己的分配行。我们的想法是通过共享相同p1

的一对p2行在assisted_eventid_evn之间建立链接
select p1.id_pers, p2.id_pers
from people p1, people p2
where exists (
    select *
    from assisted_event e1
    join assisted_event e2 on e1.id_evn=e2.id_evn
    where e1.id_pers=p1.id_pers and e2.id_pers=p2.id_pers
)

答案 2 :(得分:1)

当重新使用ANSI JOIN语法以便我可以阅读它时,您的查询将显示:

select p1.id_pers, p2.id_pers
from assisted_event ae
inner join people p1 ON (ae.id_pers = p1.id_pers)
inner join people p2 ON (ae.id_pers = p2.id_pers)

由于id_persp1主键ae.id_pers不可能同时等于p1.id_pers和{{1} }}。你需要找到另一种方法。

您根本无需加入p2.id_pers,但您可能希望填写其详细信息。您需要自行加入人与事件连接表而不是人员表以获得所需结果,过滤自连接以仅包括事件ID相同的行但人民不同。使用people而非>表示您不必使用其他通行证来过滤掉<>(a,b)配对。

类似的东西:

(b,a)

如果需要,您现在可以在select ae1.id_evn event_id, ae1.id_pers id_pers1, ae2.id_pers id_pers2 from assisted_to ae1 inner join assisted_to ae2 on (ae2.id_evn = ae1.id_evn and ae1.id_pers > ae2.id_pers) event表中添加其他联接以填充详细信息。您需要使用不同的别名将人们加入两次以填充两个不同的“边”。参见Charles Bretana的例子。