小蝦米原創做品,轉載請註明出處: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);