在oracle 10g中加入三个表

时间:2012-04-21 11:29:07

标签: sql oracle oracle10g

我有3个表,学院,学生和结果

create table college
(
clg_id int,
clg_name varchar2()50,
insert into college values(1,'GIFT');
insert into college values(2,'GITA');
insert into college values(3,'MIT');

create table student
(
clg_id int,
regno int,
sname varchar2(50)
)

insert into student values(1,10,sahar);
insert into student values(2,11,raj);
insert into student values(3,12,Payal);
insert into student values(3,13,Monalisha);
insert into student values(2,14,mary);

create table Result
(
clg_id int,
sname varchar2(50),
clg_name varchar2(50),
regno int,
dt date,
result varchar2(30)
)

insert into Result values(1,'sahar',10,'GIFT',20-02-1990,'A+');
insert into Result values(2,'raj',11,'GITA',21-02-1991,''B+);
insert into Result values(3,'monalisha',13,'MIT',22-09-2005,'A++');
insert into Result values(3,'payal',14,'MIT',22-09-2005,'C');

我想从浏览器中提供一个特定的dtclg_id,并显示result,学生姓名,大学名称以及结果日期的regno已存储。

例如:我将输入clg_id = 3dt = 22-09-2005然后显示:

 clg_name   sname      regno    result      
 MIT       monalisha   13        A++     
 MIT       payal        14       C      

我尝试了很多......我的一次尝试是

SELECT college.clg_name,student.sname,
student.regno result.result  FROM college,student,result
WHERE college.clg_id=student.clg_id=result.date;

但这是错的......请帮助。

1 个答案:

答案 0 :(得分:10)

好的,为了做到这一点,你实际上并不需要加入3个表。我可以在2上完成如下。请注意我使用了显式而不是隐式连接语法。这已经存在了几十年,应该真正使用。

select r.clg_name, s.sname, r.regno, r.result
  from result r
  join student s
    on r.regno = s.regno
 where r.clg_id = 3
   and r.dt = to_date('22-09-2005','dd-mm-yyyy')

我还创建了一个SQL Fiddle来证明这一点。

可以在两个连接中执行此操作,因为您已对数据库进行了部分非规范化并且正在复制信息,这可能导致不一致。在表result中,不需要列snameclg_name,如果学生只能在一所大学注册,则不需要clg_id

通过删除这些列,您可以确保数据库不允许错误输入数据,从长远来看可以省去很多麻烦。一个非常好的例子就是你的模式创建,result表中的Payal是regno 14,但regno表中的student是12!

如果您要正确规范化数据库(并纠正上述错误),您的查询将如下所示。请注意,我已经更改了一些命名约定,以免让事情变得更加混乱。

select c.name, s.name, s.id, r.result
  from colleges c
  join students s
    on c.id = s.college_id
  join results r
    on s.id = r.student_id
 where c.id = 3
   and r.dt =  to_date('22-09-2005','dd-mm-yyyy')

以下是该查询的架构,也在SQL Fiddle中。请注意我对您自己所做的更改:

  1. 标准化命名约定。
  2. int - > integer
  3. student表格中有多个学生,所以我将这个名称(以及其他名称)复数。
  4. 主要和外键约束 - 非常对于维护完整性非常重要。结果,必须属于必须属于大学的学生。
  5. 另请注意,您输入的日期不正确。 从不依赖隐式转换,始终明确地执行。
  6. 删除不必要的列。
  7. 我在results表中添加了一个主键。虽然这是一个代理键,即它与数据无关,但表应始终具有主键。您可能希望在student_id, dt上添加唯一约束,但我更倾向于第8点中列出的选项。
  8. 我原以为您需要另一张表格exams,并在exam_id中将results作为外键。我没有添加这个,但这是值得考虑的事情。
  9. 学生姓名已增加到最多。你只是不知道名字,最好不要过度限制。
  10. create table colleges
    (
        id integer,
        name varchar2(50),
        constraint pk_colleges primary key ( id )
      );
    
    create table students
    (
        id integer,
        name varchar2(4000), -- Use the maximum. Names are impossible to predict
        college_id integer,
        constraint pk_students primary key ( id ),
        constraint fk_student_college foreign key ( college_id )
           references colleges ( id )
    );
    
    create table Results
    (
        id integer,
        student_id integer,
        dt date,
        result varchar2(30),
        constraint pk_results primary key ( id ),
        constraint fx_result_student foreign key ( student_id )
           references students ( id )
    );
    

    进一步阅读: