【问题标题】:Joining three tables in oracle 10g在 oracle 10g 中连接三个表
【发布时间】:2012-04-21 11:29:06
【问题描述】:

我有 3 个表,College、Student 和 Result

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;

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

【问题讨论】:

    标签: sql oracle oracle10g


    【解决方案1】:

    好的,为了做到这一点,您实际上不需要加入 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,但在 student 表中是 regno 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. 学生姓名已增加到最大值。您只是无法通过名称来判断,最好不要过度限制。
    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 )
    );
    

    延伸阅读:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-26
      相关资源
      最近更新 更多