天生舞男

我喜欢谦虚的学习各种...,希望自己能坚持一辈子,因为即使一张卫生巾也是有它的作用.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SQL基础语法

Posted on 2005-09-11 13:52  天生舞男  阅读(1395)  评论(0编辑  收藏  举报

基础是很重要的,以下通过三个表学生表S,课程表C,学生课程表SC
来举例说明SQL的操作:
create table S
(
 S# char(8),
 SNAME varchar(20) not null,
 AGE tinyint,
 SEX bit default 1,
 DNAME char(10),
 primary key(S#),
 check(SEX =0 or SEX = 1)
)

create table C
(
 C# char(8),
 CNAME varchar(8) not null,
 CREDIT tinyint,
 PC# char(8),
 primary key(C#),
 foreign key(PC#) references C(C#)
)

create table SC
(
 S# char(8),
 C# char(8),
 GRADE tinyint,
 primary key (S#,C#),
 foreign key(S#) references S(S#) on delete cascade,
 foreign key(C#) references C(C#) on delete cascade,
 check((GRADE is null) or (GRADE between 0 and 100))
)

SELECT colid,name,xtype,length,xusertype,offset
FROM syscolumns
WHERE id = object_id('s')

SELECT SNAME,CNAME
FROM S,C,SC
WHERE S.S# = SC.S# AND C.C# = SC.C#

--列出每个学生的姓名及其所选修的课程名
SELECT SNAME,CNAME
FROM S,C,SC
WHERE S.S# = SC.S#
      AND C.C# = SC.C#

--给出所有学生的学号,姓名以及出生年份
SELECT S# as '学号',SNAME as '姓名',2005 - AGE as '出生年份'
FROM S

--找出选修了'002'课程并且其成绩比'0002'学生选修该门课程成绩高的学生学号
SELECT Y.S#
FROM SC as X,SC as Y
WHERE  X.S# =  '0002'
      and X.C# ='002'
      and Y.C# ='002'
      and Y.GRADE > X.GRADE

--按学号升序输出SC关系,对应同一个学生的选课元组按课程号降序排列
SELECT S#,C#,GRADE
FROM SC
ORDER BY S# asc,C# desc

--列出所有成绩都及了格的学生的平均成绩
SELECT S#,avg(GRADE)
FROM SC
GROUP BY S#
HAVING min(GRADE) >= 60

--列出每个学生所有及格了的课程的平均成绩
SELECT S#,avg(GRADE)
FROM SC
WHERE GRADE >= 20
GROUP BY S#

--列出选修了001课程的学生的学号及姓名
SELECT S#,SNAME
FROM S
WHERE S# in
      (
 SELECT S#
 FROM SC
 WHERE C# = '001'
      )

--找出平均成绩最高的学生号
SELECT S#
FROM SC
GROUP BY S#
HAVING AVG(GRADE) >= all
       (
 SELECT AVG(GRADE)
 FROM SC
 GROUP BY S#
       )
--<> some 运算符与not in 有所不同,<> some表示不等于a或不等于b或不等于c
--而not in 表示不等于a且不等于b且不等于c,所以<>all 与 not in 意义相同

--列出选修了全部课程的学生姓名
--本查询等价于任意课程,所求学生选之 <=> 不存在任何一门课程,所求学生没有选之
SELECT SNAME
FROM S
WHERE not exists
(
 SELECT *
 FROM C
 WHERE not exists
 (
  SELECT *
  FROM SC
  WHERE SC.C# = C.C#
  AND SC.S# = S.S#
 )
)


--插入功能

--插入单条元组
INSERT INTO S values('s5','王郦',25,0,'计算机系')
--将平均成绩大于30的学生加入到excellent表中
create table excellent
(
 S# char(8),
 GRADE tinyint
)
INSERT INTO excellent(S#,GRADE)
SELECT S#,AVG(GRADE)
FROM SC
GROUP BY S#
HAVING AVG(GRADE) > 30

--从S表中删除平均成绩<50的记录
DELETE FROM S
WHERE S# in
(
 SELECT S#
 FROM SC
 GROUP BY S#
 HAVING AVG(GRADE) < 60
)

--将lixiaojian同学选修001课程的成绩改为该门课程的平均成绩
UPDATE SC
SET GRADE =
    (
 SELECT avg(GRADE)
        FROM SC
 WHERE C# = '001'
    ) 
WHERE S# =
    (
 SELECT S#
 FROM S
 WHERE SNAME ='lixiaojian'
    )
AND C# = '001'

--常见错误的写法
--求成绩最高的学生
SELECT S#
FROM SC
WHERE GRADE = max(GRADE)
--错误的原因:
--聚合不应出现在 WHERE 子句中,除非该聚合位于 HAVING 子句或选择列表所包含的子查询中,
--并且要对其进行聚合的列是外部引用。

--求成绩最高的学生的学好及其成绩
SELECT S#,max(GRADE)
FROM SC
--错误的原因:
--列 'SC.S#' 在选择列表中无效,因为该列未包含在聚合函数中,并且没有 GROUP BY 子句。


--求选修了课程的学生人数
SELECT count(S#)
FROM SC
--错误的原因:
--SQL的返回结果是缺省保留重复值的,需要用distinct关键字来去除
SELECT count(distinct S# )
FROM SC


--列出同时选修了001和002课程的学号
SELECT S#
FROM SC
WHERE SC.C# = '001' AND SC.C#='002'
--错误的原因:
--一个课程号不可能同时等于两个不同的值
--正确的写法是
SELECT S#
FROM SC
WHERE SC.C# = '001'
      AND S# in
      (
 SELECT S#
 FROM SC
 WHERE C# = '002'
      )