SQL基本语句

小虾米原创做品,转载请注明出处:https://www.cnblogs.com/shrimp-can/p/9898735.htmlhtml

小虾米最近在找工做,笔试题少不了SQL语句,几年没有碰过数据库都忘记了,复习了一下,将经常使用的简单的SQL语句以例子的形式系统的整理一下。数据库

此文章根据书《数据库系统概念》第三章整理而成。函数

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------测试

贯穿整个例子的关系有以下5个,最前面是关系名字,‘:’后面是该关系的属性ui

1.建筑department:系名dept_name, 建筑building, 预算budgetspa

2.课程course:课程号course_id,课程名称title,课程所属的系名dept_name,学分creditshtm

3.教师信息instructor:教师号ID,教师名字name,教师所在的系dept_name,薪资salaryblog

4.开课信息section:课程号course_id,课程段标识sec_id,学期semester,年份year,课程所在建筑building,课程所在教室号room_number,时间档序号time_slot_idci

5.教学信息teaches:教室号ID,课程号course_id,课程信息序号sec_id,学期semester,年份year字符串

6.选课信息takes:学生学号ID,课程标识course_id,课程段标识sec_id,学期semester,年份year,成绩grade

7.学生信息student:学生学号ID,学生姓名name,学生所在系dept_name,总学分tot_cred

 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1、关系的建立与删除create、delete

1.表的建立create table

例1.1:建立一个department关系

create table department

(dept_name varchar(20),

building varchar(15),

budget numeric(12,2),

primary key (dept_name)); //主码

2.表的删除drop table

例1.2:删除关系department

drop table department;

2、单关系简单查询select

1.基本的单关系查询

例2.1:找出全部教师的名字

select name from instructor;

例2.2:找出全部教师所在的系名

select dept_name from instructor;

:由于instructor关系中多个老师能够在一个系中,因此上述查询结果中会有重复的系名

2.去除重复distinct

例2.3:找出全部教师所在的系名,去除重复

select distinct dept_name from instructor;

3.显式指明不去除重复all

例2.4:例2中指明不去除重复

select all dept_name from instructor;

4.算数表达式+、-、*、/运算

例2.5:将教师的薪资增加10%

select ID, name, dept_name, salary*1.1 from instructor;

5.where子句

选出知足特定条件的元组,可使用逻辑连词and、or 和not。可使用运算符<、<=、>、>=、=和<>

例2.6:找出全部在Comuter Science系而且工资超过70000美圆的教师的姓名

select name from instructor where dept_name='Computer Science' and salary>70000;

 3、多关系简单查询

1.简单查询

例3.1:找出全部教师的姓名,以及他们所在系的名称和系所在建筑的名称

select name, instructor.dept_name, building from instructor, department where instructor.dept_name=department.dept_name;

例3.2:找出Computer Science系的教师名和课程标识

select name, course_id from instructor, teaches where instructor.ID=teaches.ID and dept_name='Computer Science';

2.天然链接natural join

天然链接做用于两个关系,并产生一个关系做为结果,只考虑在关系模式中出现相同属性的取值相同的状况

例3.3:例2能够用天然链接改成

select name, course_id from instructor natural join teaches;

例3.4:列出教师的名字和他们所讲授的课程的名称

select name, title from instructor natural join teaches, course where course.course_id=teaches_course_id;

3.链接中指定哪些列相等join...using

例3.5:例4能够改成

select name, title from (instructor natural join teaches) join course using (course_id);

4、基本运算

1.改名运算as

例4.1:对于全部讲授课程的教师,找出他们的姓名以及所讲授的课程标识,将查找结果的教师名字改成instructor_name

select name as instructor_name, course_id from instructor, teaches where instructor.ID=teaches.ID;

例4.2:将例1中的instructor关系和teaches关系从新命名为T和S

select T.name, S.course_id from instructor as T, teaches as S where T.ID=S.ID

例4.3:找出知足下面条件的全部教师的姓名,他们的工资至少比Biology系某一个教师的工资要高(去除重复的教师姓名)

select distinct T.name from instructor as T, instructor as S where T.salary>S.salary and S.dept_name='Biology';

2.字符串运算

2.1.字符串匹配like %/_

%:匹配任意字符串

_:匹配任意一个字符

Intro%:匹配任意以"Intro"开头的字符串

%Comp%:匹配任意包含"Comp"子串的字符串

_ _ _:匹配只含有三个字符的字符串

_ _ _%:匹配至少含有三个字符的字符串

例4.4:找出所在建筑名称中包含子串‘Watson’的全部系名

select dept_name from department where building like '%Watson%';

2.2.转义字符的处理escape '\'

like 'ab\%cd%' escape '\':匹配全部以'ab%cd'开头的字符串

like 'ab\\cd%' escape '\':匹配全部以ab\cd开头的字符串

3.select中选择全部的属性*

例4.5:找出全部讲授了课程的教师信息

select instructor.* from instructor, teaches where instructor.ID=teaches.ID;

4.排列查询结果中元组的显示次序order by

order by默认升序,desc表示降序,asc表示升序

例4.6:按字母顺序列出Physics系的全部教师名字

select name from instructor where dept_name='Physics' order by name;

例4.7:按salary的降序列出整个instrutor关系,若是几位教师的工资相同,就按他们的名字升序排列

select * from instructor order by salary desc, name asc;

5.where子句的谓词between... and...

例4.8:找出工资在90000美圆和100000美圆之间的教师的姓名

select name from instructor where salary between 90000 and 100000;

它与此SQL语句等价

select name from instructor where salary>=90000 and salary<=100000;

例4.9:查找Biology系讲授了课程的全部教师的姓名和他们所讲授的课程标识

select name, course_id from instructor and teaches where (instructor.ID, dept_name)=(teaches.ID, 'Biology');

它与下面的SQL语句等价

select name, course_id from instructor and teaches where instructor.ID=teaches.ID and dept_name='Biology';

5、集合运算

1.并运算union

union会自动去除重复,要想保留全部的重复信息,用union all替代union

例5.1:找出在2009年秋季开课或者在2010年春季开课或者两个学期都开课的全部课程标识

(select course_id from section where year=2009 and semester='Fall') union 

(select course_id from section where year=2010 and semester='Spring');

2.交运算intersect

intersect也会自动去除重复,要想保留全部的重复,用intersect all替代intersect

例5.2:找出在2009年秋季和2010年春季同时开课的全部课程序号的集合

(select course_id from section where year=2009 and semester='Fall') intersect 

(select course_id from section where year=2010 and semester='Spring');

3.差运算except

将会在第一个关系中减去全部在关系2中出现的元祖,最后的结果将不会有重复的元组出现。若是想保留重复,用except all替代except

例5.3:找出在2009年秋季开课但不在2010年春季开课的全部课程序号

(select course_id from section where year=2009 and semester='Fall') except

(select course_id from section where year=2010 and semester='Spring');

6、汇集函数

1.基本汇集

平均值:avg

最小值:min

最大值:max

总和:sum

计数:count

例6.1:找出Computer Science系教师的平均工资

select avy(salary) from instructor where dept_name='Comouter Science';

例6.2:例1中给平均工资赋个新名称avg_salary

select avy(salary) as avg_salary from instructor where dept_name='Comouter Science';

例6.3:找出在2010年春季学期讲授课程的教师总数

select count (distinct ID) from teaches where semester='Spring' and year=2010;

注意:一个教师可能讲授几个课程段,可是在这里只应被计算一次,所以须要去除重复

例6.4:计算课程信息关系中的元祖个数

select count (*) from course;

2.分组汇集group by

group by将在该属性取值相同的元组划分为一组

例6.5:找出每一个系的平均工资

select avy(salary) from instructor group by dept_name;

例6.6:找出每一个系在2010年春季讲授了课程的教师人数

select dept_name, count(distinct ID) from teaches natural join instructor  where semester='Spring' and year=2010 group by dept_name;

3.having子句

对group by子句构成的分组限定条件

例6.7:找出教师平均工资超过42000美圆的系

select dept_name, avg(salary) as avg_salary from instructor group by dept_name having avg(salary)>42000;

例6.8:对于在2009年讲授的每一个课程段,若是该课程段有至少2名学生选课,找出选修该课程段的全部学生的总学分的平均值

select course_id, year, semester, sec_id, avg(tot_cred) from takes natural join student group by course_id, sec_id, semester, year having count(ID)>=2;

7、嵌套子查询

1.集合成员的资格in, not in

例7.1:找出在2009年秋季开课,同时也在2010年春季开课的全部课程

select distinct course_id from section where semester='Fall' and year=2009 and course_id in

(select course_id from section where semester='Spring' and year=2010);

例7.2:找出在2009年秋季开课,可是不在2010年春季开课的全部课程

select distinct course_id from section where semester='Fall' and year=2009 and course_id not in

(select course_id from section where semester='Spring' and year=2010);

 例7.3:查找既不叫‘Mpzart’也不叫'Einstein'的教师姓名

select distinct name from instructor where name not in ('Mozart', 'Einstein');

例7.4:找出不一样的学生总数,他们选修了ID为10101的教师所讲授的课程

select count(sidtinct ID) from takes where course_id, sec_id, semester, year in (select course_id, sec_id, semester, year from teaches where teaches.ID=10101);

2.集合的比较

至少比某一个要大:>some

此外还有:<some,<=some,>=some,=some(等价于in),<>some

比全部的都大:>all

此外还有:<all,<=all,>=all,=all,<>all(等价于not in)

例7.5:找出知足下面条件的全部教师的姓名,他们的工资至少比Biology系某一个教师的工资要高

select name from instructor where salary >some (select salary from instructor where dept_name='Biology');

例7.6:找出知足下面条件的全部教师的姓名,他们的工资比Biology系每一个教师的工资都高

select name from instructor where salary >all (select salary from instructor where dept_name='Biology');

例7.7:找出平均工资最高的系

select dept_name from instructor where avg(salary) >=all (select avg(salary) from instructor group by dept_name);

3.空关系测试exists, not exists

关系A包含关系B写成 not exists (B except A)

例7.8.找出在2009年秋季学期和2010年春季学期同时开课的全部课程标识

select course_id from section as S where year=2009 and semester='Fall' and exists

(select * from section as T where year=2010 and semester='Spring' and S.course_id=T.course_id);

例7.9:找出选修了Biology系开设的全部课程的学生

select S.ID, S.name from student as S where not exists ((select course_id from course where dept_name='Biology') except (select T.course_id from takes as T where S.ID=T.ID));

4.重复元组存在性测试unique, not unique

例7.10:找出全部在2009年最多开设一次的课程

select T.course_id from course as T where unique (select R.course_id from section as R where T.course_id=R.course_id and R.year=2009);

或者

select T.course_id from course as T where 1 >= (select count(R.course_id) from section as R where T.course_id=R.course_id and R.year=2009);

例7.11:找出全部在2009年最少开设两次的课程

select T.course_id from course as T where not unique (select R.course_id from section as R where T.course_id=R.course_id and R.year=2009);

5.from子句中的子查询

例7.12:找出系平均工资超过42000美圆的那些系中教师的平均工资

select dept_name, avg_salary from (select dept_name, avg(salary) as avg_salary from instructor group by dept_name) where avg_salary > 42000;

例7.13:能够给from子句中的查询结果关系进行命名,并对其属性进行命名

select dept_name, avg_salary from (select dept_name, avg(salary) from instructor group by dept_name) as dept_avg (dept_name, avg_salary) where avg_salary > 42000;

例7.14:找出全部系中工资总额最大的系

select dept_name, max(tot_salary) from (select dept_name, sum(salary) from instructor group by dept_name) as dept_total (dept_name, tot_salary);

6.with子句

 with子句提供定义临时关系的方法

例7.15:找出具备最大预算值的系

with max_budget (value) as (select max(budget) from department)

select budget from department, max_budget where departmen.budget=max_budget.value;

例7.16:查找全部工资总额大于全部系平均工资总额的系

with dept_total (dept_name, value) as (select dept_name, sum(salary) from instructor group by dept_name),

dept_total_avg(value) as (select avg(value) from dept_total);

select dept_name from dept_total, dept_total_avg where dept_total.value > dept_total_avg.value;

7.标量子查询

子查询出如今返回单个值的表达式可以出现的任何地方。

例7.17:列出全部的系和他们拥有的教师数

select dept_name, (select count(*) from instructor where department.dept_name=instructor.dept_name) as num_instructors from department;

8、数据库的修改

1.删除delete

删除整个关系前面咱们已经讲了,用drop table,这里是删除关系中的元组

例8.1:从instructor关系中删除与Finance系教师相关的全部元组

delete from instructor where dept_name='Finance';

例8.2:删除全部工资在13000美圆到15000美圆之间的教师

delete from instructor where salary between 13000 and 15000;

例8.3:从instructor关系中删除全部这样的教师元组,他们在位于Watson大楼的系工做

delete from instructor where dept_name in (select dept_name from department where building='Watson');

例8.4:删除工资低于大学平均工资的教师记录

delete from instructor where salary < (select avg(salary) from instructor);

2.插入insert into

例8.5:插入的信息是Comouter Science系开设的名为'Database System'的课程CS-437,它有4个学分

insert into course values('CS-437', 'Database System', 'Computer Science', 4);

例8.6:例5中指定属性插入

insert into course (course_id, title, dept_name, credits) values('CS-437', 'Database System', 'Computer Science', 4);

例8.7:咱们想让Music系每一个修满144学分的学生成为Music系的教师,其工资为18000美圆

insert into instructor select ID, name, dept_name, 18000 from student where dept_name='Music' and tot_cred>=144;

3.更新update

例8.8:将全部教师的工资增加5%

update instructor set salary=salary*1.05;

例8.9:给工资低于70000美圆的教师工资增加5%

update instructor set salary=salary*1.05 where salary<70000;

例8.10:对工资低于平均数的教师涨5%的工资

update instructor set salary=salary*1.05 where salary<(select avg(salary) from instructor);

例8.11:给工资超过100000美圆的教师涨3%的工资,其他教师涨5%

update instructor set salary=salary*1.03 where salary>100000;

update instructor set salary=salary*1.05 where salary<=100000;

例8.12:将例11用case结构

update instructor

set salary = case

                    when salary <=100000 then salary*1.05

                    else salary*1.03

          end

例8.13:把每一个student元组的tot_cred属性值设为该学生成功学完的课程学分的总和;假设学生在某门课程上的成绩既不是'F'也不是空,那么他成功学完了这门课程

update student set tot_cred = (select sum(credits) from takes natural join course where student.ID=takes.ID and takes.grade <>'F' and takes.grade is not null);

相关文章
相关标签/搜索