1
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 行。

我究竟做错了什么?

4

3 回答 3

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

这会生成所有协助同一事件的人 [情侣]。使用您的模式,无法将结果限制在他们在同一天提供帮助的情况下。假设是,如果他们协助同一事件,那么该事件只能发生在一天。

于 2013-06-08T01:48:43.320 回答
2

您选择了两个人,因此您还需要选择两行,因为每个人在表assisted_event中都有自己的分配行。这个想法是在一对共享相同的行assisted_event之间建立一个p1链接p2assisted_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
)
于 2013-06-08T01:49:43.483 回答
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_pers是 的主键p1所以不可能ae.id_pers同时等于p1.id_persp2.id_pers。你需要找到另一种方法。

您根本不需要为此加入people,尽管您可能想要填写他们的详细信息。您需要自联接人员到事件联接表而不是人员表以获得所需的结果,过滤自联接以仅包括事件 ID 相同但人员不同的行。使用>而不是<>意味着您不必使用另一个通道来过滤掉(a,b)vs(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)

如果需要,您现在可以在eventpersion表上添加其他连接以填充详细信息。您需要将具有不同别名的人加入两次以填充两个不同的“方面”。参见 Charles Bretana 的例子。

于 2013-06-08T01:46:45.090 回答