3

我有 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;

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

4

1 回答 1

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 是regno14,但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. 我原以为您会需要另一个表 ,examsexam_idresults. 我没有添加这个,但这是值得考虑的事情。
  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 )
);

延伸阅读:

于 2012-04-21T12:44:16.103 回答