【问题标题】:SQL joins result in repeating resultsSQL 连接导致重复结果
【发布时间】:2012-05-12 20:46:28
【问题描述】:

我创建了这样的表:

create table utilisateur(
 id_util number(10) primary key,
 nom varchar2(10) not null,
 prenom varchar2(10) not null,
 date_naissance date not null,
 adress varchar2(20)
);

create table cour(
 id_cour number(10) primary key,
 c_nom varchar2(20) not null,
 auteur varchar2(20) not null
);

create table etude(
 fk_util number(10) references utilisateur(id_util),
 fk_cour number(10) references cour(id_cour),
 primary key(fk_util,fk_cour)
);

create table examen(
 id_ex number(10) primary key,
 ex_nom varchar2(20) not null,
 temp date,
 fk_cour number(10) references cour(id_cour)
);

create table passer(
 fk_util number(10) references utilisateur(id_util),
 fk_ex number(10) references examen(id_ex),
 primary key(fk_util,fk_ex),
 note number(4)
);

create table certificat(
 cert_nom varchar2(20),
 prix varchar2(10),
 code varchar2(10) primary key,
 fk_ex number(10),
 fk_util number(10)
);

create table signet(
 id_sign number(10) primary key,
 s_nom varchar2(20) not null,
 depand_par varchar2(20) not null,
 fk_util number(10) references utilisateur(id_util)
);

问题是我想查看所有用户(utilisateur),他们正在阅读哪门课程(cour),他们通过了哪门考试(examen)以及他们获得了哪些证书(certificat)已收到。

我尝试使用内部连接、左右连接、完全连接、视图来执行此操作,但没有成功。如果我注册了 3 门课程和 2 门考试,那么我会看到一些重复。我在想可能是我的数据库出了点问题。

【问题讨论】:

  • 您能发布您正在使用的查询吗? 2个考试是针对一门课程的吗?这在此架构中是可能的,并且可能导致您描述的行为。
  • 这是查询: select utilisateur.nom, cour.c_nom,examen.ex_nom from utilisateur left join etude on utilisateur.id_util=etude.fk_util left join cour on etude.fk_cour=cour.id_cour left在 utilisateur.id_util=passer.fk_util 上加入 passer,在 passer.fk_ex=examen.id_ex 上左加入考试;

标签: sql oracle join


【解决方案1】:

这个查询

select utilisateur.nom
       , cour.c_nom
       , examen.ex_nom
from utilisateur left join etude on utilisateur.id_util=etude.fk_util 
left join cour on etude.fk_cour=cour.id_cour 
left join passer on utilisateur.id_util=passer.fk_util 
left join examen on passer.fk_ex=examen.id_ex;

不考虑考试与课程相关的事实。我认为没有必要为您想要实现的目标进行外部连接,所以试试这个。

select utilisateur.nom
     , cour.c_nom
     , examen.ex_nom
from utilisateur join etude on utilisateur.id_util=etude.fk_util 
                 join cour on etude.fk_cour=cour.id_cour 
                 join passer on utilisateur.id_util=passer.fk_util 
                 join examen on cour.id_cour = examen.fk_cour;

编辑:这比我第一次看到的要复杂一些,我在下面添加了一个新的解决方案。我做的第一件事是在查询中添加一些别名,如果您不在某些版本的 oracle 上使用别名,则在 3 个或更多表之间进行 ansi 连接会出现问题。别名通常是一件好事,无论如何我都添加了它们。我还将一些表格移动到内联视图中,以使问题对我自己更清楚。除了整理之外,我所做的唯一真正的改变是添加这一行:-

和 paex.id_ex = coex.id_ex

我已经根据我按照您的描述创建的一些数据测试了这个查询,它似乎可以满足您的需求。

    SELECT ut.id_util
  ,ut.nom
  ,coex.c_nom
  ,paex.id_ex
  ,paex.ex_nom FROM   utilisateur ut LEFT JOIN (SELECT c_nom
             ,ex_nom
             ,co.id_cour
             ,id_ex 
             ,et.fk_util               
       FROM etude et JOIN cour co ON et.fk_cour = co.id_cour
                LEFT JOIN examen ex2 ON co.id_cour = ex2.fk_cour) coex ON coex.fk_util = ut.id_util LEFT JOIN (SELECT *
       FROM passer pa JOIN examen ex  ON pa.fk_ex   = ex.id_ex) paex ON paex.fk_util = ut.id_util 
                                                                    AND paex.id_ex = coex.id_ex ORDER BY id_util;

【讨论】:

    猜你喜欢
    • 2013-02-25
    • 2013-04-22
    • 2020-10-30
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多