SQL实战
结构化查询语言(Structured Query Language)简称SQL
SQL语言共分为四大类:
DQL:数据查询语言,关键字包括select, from where等等
DML:数据操纵语言,INSERT、UPDATE、DELETE
DDL:数据定义语言,CREATE TABLE/VIEW/INDEX/SYN/CLUSTER、ALTER、DROP
DCL:数据控制语言,GRANT、ROLLBACK、COMMIT
DDL-导入数据
在MySQL中导入DDL.sql,DDL.sql具体内容如下:
create table classroom
(
building varchar(15),
room_number varchar(7),
capacity numeric(4,0), -- 精度,小数
primary key (building, room_number)
);
create table department
(
dept_name varchar(20),
building varchar(15),
budget numeric(12,2) check (budget > 0),
primary key (dept_name)
);
create table course
(
course_id varchar(8),
title varchar(50),
dept_name varchar(20),
credits numeric(2,0) check (credits > 0),
primary key (course_id),
foreign key (dept_name) references department (dept_name)
on delete set null
);
create table instructor
(
ID varchar(5),
name varchar(20) not null,
dept_name varchar(20),
salary numeric(8,2) check (salary > 29000),
primary key (ID),
foreign key (dept_name) references department (dept_name)
on delete set null
);
create table section
(
course_id varchar(8),
sec_id varchar(8),
semester varchar(6)
check (semester in ('Fall', 'Winter', 'Spring', 'Summer')),
year numeric(4,0) check (year > 1701 and year < 2100),
building varchar(15),
room_number varchar(7),
time_slot_id varchar(4),
primary key (course_id, sec_id, semester, year),
foreign key (course_id) references course (course_id)
on delete cascade,
foreign key (building, room_number) references classroom (building, room_number)
on delete set null
);
create table teaches
(
ID varchar(5),
course_id varchar(8),
sec_id varchar(8),
semester varchar(6),
year numeric(4,0),
primary key (ID, course_id, sec_id, semester, year),
foreign key (course_id, sec_id, semester, year) references section (course_id, sec_id, semester, year)
on delete cascade,
foreign key (ID) references instructor (ID)
on delete cascade
);
create table student
(
ID varchar(5),
name varchar(20) not null,
dept_name varchar(20),
tot_cred numeric(3,0) check (tot_cred >= 0),
primary key (ID),
foreign key (dept_name) references department (dept_name)
on delete set null
);
create table takes
(
ID varchar(5),
course_id varchar(8),
sec_id varchar(8),
semester varchar(6),
year numeric(4,0),
grade varchar(2),
primary key (ID, course_id, sec_id, semester, year),
foreign key (course_id, sec_id, semester, year) references section (course_id, sec_id, semester, year)
on delete cascade,
foreign key (ID) references student (ID)
on delete cascade
);
create table advisor
(
s_ID varchar(5),
i_ID varchar(5),
primary key (s_ID),
foreign key (i_ID) references instructor (ID)
on delete set null,
foreign key (s_ID) references student (ID)
on delete cascade
);
create table time_slot
(
time_slot_id varchar(4),
day varchar(1),
start_hr numeric(2) check (start_hr >= 0 and start_hr < 24),
start_min numeric(2) check (start_min >= 0 and start_min < 60),
end_hr numeric(2) check (end_hr >= 0 and end_hr < 24),
end_min numeric(2) check (end_min >= 0 and end_min < 60),
primary key (time_slot_id, day, start_hr, start_min)
);
create table prereq
(
course_id varchar(8),
prereq_id varchar(8),
primary key (course_id, prereq_id),
foreign key (course_id) references course (course_id)
on delete cascade,
foreign key (prereq_id) references course (course_id)
);其他DDL语句包括
drop:
drop table r
alter:
alter table r add [字段名] [类型]alter table r drop [字段名]alter table r modify [字段名] [类型]Alter Table 表名 Add Constraint 约束名 约束类型 具体的约束类型Alter Table 表名 Drop Constraint 约束名
create view <视图名> as <DQL语句> [with check option]
Most SQL implementations allow updates only on simple views
The from clause has only one database relation.
The select clause contains only attribute names of the relation, and does not have any expressions, aggregates, or distinct specification.
Any attribute not listed in the select clause can be set to null
The query does not have a group by or having clause.
DQL执行顺序
from
where
group by
having
select
order by
The select Clause
Find the department names of all instructors, and remove duplicates
在没有聚集函数的情况下,distinct 对于
select的字段集合去重
The where Clause
To find all instructors' names in Comp. Sci. dept with salary > 80000
The from Clause
Find the names of all instructors who have taught some course and the course_id
Join
join原理的伪代码实现:
join的一个实例:
简单验证一下:
select count(*) from instructor;得12select count(*) from department;得7select count(*) from instructor , department;得84
$84 = 12 \times 7$,符合笛卡尔乘积。
现在我们加上限制:
Inner join 与 Outer join
Outer Join:An extension of the join operation that avoids loss of information. Computes the join and then adds tuples form one relation that does not match tuples in the other relation to the result of the join.
对比如下:
外连接一定需要
on后面的语句
Natural Join
等值连接在进行多表联合查询时通过**“=”**等号来连接多张表之间相字段对应的值,其产生的结果会出现重复列。
自然连接(Naturaljoin)是一种特殊的等值连接,它要求两个关系中进行比较的分量必须是相同的属性组,并且在结果中把重复的属性列去掉。而等值连接并不去掉重复的属性列。
column used in NATURAL join cannot have qualifier
The Rename Operation
Find the names of all instructors who have a higher salary than some instructor in 'Comp. Sci'.
oracle 不允许出现
as
String Operations
Find the names of all instructors whose name includes the substring “dar”.
Pattern matching examples:
'Intro%' matches any string beginning with “Intro”.
'%Comp%' matches any string containing “Comp” as a substring.
'_ _ _' matches any string of exactly three characters.
'_ _ _ %' matches any string of at least three characters.
Ordering the Display of Tuples
List in reverse alphabetic order the names of all instructors
order by默认升序排序(ASC),不能放在子查询中
Rank
多出一列作为排序编号,用于在分组内部进行排序。需要注意的是:
RANK()是跳跃排序,即:如果有两个第1名,则接下来就是第3,忽略第2的情况。
使用RANK()的时候,空值是最大的,如果排序字段为null,可能造成null字段排在最前面,影响排序结果。
Partition by
用于给结果集分组,如果没有指定,则是对整个结果集作为一个分组。
Dense Rank
RANK()是跳跃式排序,如果不需要跳跃式排序,可以使用DENSE_RANK()。当排序编号并列以后,下一个不空出所占的编号。注意与上面RANK比较
Row Number
ROW_NUMBER()不需要考虑是否并列,哪怕根据条件查询出来的数值相同也会进行连续排名。
Ntail
NTILE(n)将数据集合平均分配到指定的数量的n个桶中,将桶号分配给每一行。
例如5行数据,分成2组,就会前面3个,后面2个,默认把多余的行分给前面;分成3组,第一组就会2个,第二组就会2个,第三组就会1个。
Where Clause Predicates
Find the names of all instructors with salary between $90,000 and $100,000 (that is, ≥ $90,000 and ≤ $100,000)
Set Operations
注意属性数量和属性数据结构兼容
unionintersect或者minusexceptunion: 对两个结果集进行并集操作, 不包括重复行,相当于distinct, 同时进行默认规则的排序
union all: 对两个结果集进行并集操作, 包括重复行, 即所有的结果全部显示, 不管是不是重复
Find courses that ran in Fall 2017 but not in Spring 2018
有些数据库不支持关键字except,改成minus
some,any,all
some与any同义,some基于或运算,all基于与运算
可以使用
< some(相当于< max)
<= some(相当于<= max)
> some(相当于> min)
>= some(相当于>= min)
= some(相当于in)
<> some(不同于 not in,<>some本质是
!=a || !=b ...,not in 本质是!=a && !=b ...)< all(相当于< min)
<= all(相当于< min)
> all(相当于> max)
>= all(相当于>= max)
= all(不同于in,应该说除了标量子查询其他恒为假)
<> all(相当于 not in)
Null Values
The result of any arithmetic expression involving null is null,(Example: 5 + null returns null)
SQL treats as unknown the result of any comparison involving a null value (Example*: 5 <* null or null <> null or null = null)
instead, use predicates is null and is not null
Find all instructors whose salary is null
TRUE > UNKNOWN > FALSE:
(true and unknown) = unknown
(false and unknown) = false
(unknown and unknown) = unknown
(unknown or true) = true
(unknown or false) = unknown
(unknown or unknown) = unknown
Aggregate Functions
Find the total number of instructors who teach a course in the Spring 2018 semester
Find the average salary of instructors in each department
Find the names and average salaries of all departments whose average salary is greater than 42000
聚集函数忽略NULL值,包括count(字段名),唯一不忽略空值的是count(*)
加不加distinct差别很大
group by 之后可以加多个字段
Nested Subqueries嵌套子查询
Set Membership
Name all instructors whose name is neither “Mozart” nor Einstein”
Find courses offered in Fall 2017 and in Spring 2018
或者
Set Comparison
Find names of instructors with salary greater than that of some (at least one) instructor in the Biology department.
或者:
Find the names of all instructors whose salary is greater than the salary of all instructors in the Biology department.
Test for Empty Relations
Find all students who have taken all courses offered in the Biology department.
相关子查询
相关子查询:内部子查询不独立,比如借用到外层的表。
不相关子查询:内部子查询独立。
不相关子查询可以理解为先执行内部独立的子查询,再和外部查询。
相关子查询举一个例子:
我们知道WHERE是以行为单位进行保留或去除,比如在处理section表的第一行时:
子查询“退化”为:
查询结果为:
为空,EXISTS返回FALSE,这一行被去除。
以此类推,在处理每一行时都要进行一次子查询,效率较低。
Subqueries in the From Clause
Find the average instructors’ salaries of those departments where the average salary is greater than $42,000.
或者:
With Clause
Find all departments with the maximum budget
Find all departments where the total salary is greater than the average of the total salary at all departments
Scalar Subquery
List all departments along with the number of instructors in each department
或者:
特殊例子
DML
Deletion
Delete all instructors
Delete all instructors from the Finance department
Insertion
Add a new tuple to course
Make each student in the Music department who has earned more than 144 credit hours an instructor in the Music department with a salary of $18,000.
Updates
Give a 5% salary raise to instructors whose salary is less than average
update instructor set salary = salary * 1.05 where salary < (select avg (salary) from instructor);
函数补充
nvl(exper1, exper2):如果exper1为NULL,用exper2代替length(exper):对于字符串字段求其长度round(exper, n):对于小数字段exper,保留位小数concat(exper1, exper2):字符串拼接,拼接多个就嵌套。
综合练习
Find the students who have registered some course at least 2 times. For each student as such, following information should be listed:
Name of the student
Title of the course
Count of registered record of the student for the course
Find the students who have never registered any course. For each student as such, following information should be listed:
ID of the student
Name of the student
Find the sections which have register records having unknown grade information. For each section as such, following information should be listed:
Title of the course corresponding to the section
Id of the section
Year of the section
Semester of the section
Find the students who enroll to the department having 4 instructors at least. For each student as such, following information should be listed:
Id of the student
Name of the student
Name of the department the student enrolled to
Find the department which hired instructors whose name contain ‘世’. For each department as such, following information should be listed:
Name of the department
Building of the department
Instructor count of the department
Find the courses which have no ‘F’ grade record ever. Note: the courses which have never be registered should be included. For each course as such, following information should be listed:
Course_id the course
Title of the course
Count of section corresponding to the course
Get the grade distribution of all the sections having records in table takes Note: there’s some grade like ‘A-’. For each section grade distribution as such, following information should be listed:
Course_id of the section
Year of the section
Semester of the section
ID number of the section
Count of grade A records
Count of grade B records
Count of grade C records
Count of grade D records
Count of grade F records
Count of records without grade information
另外一种写法,本质一样:
提醒:column used in NATURAL join cannot have qualifier
不能写成:
Get the total credit hours in a week for every course which has has corresponding sections in every semester. For each course as such , following information should be listed:
ID of the course
Year of the course ’s sections
Semester of the course ’s sections
Count of the Count of the course ’s sections in the corresponding year and semester
Total Credit hours in a week. Note: 1 credit hour = 50 minutes
Find the pairs of student and instructor which the student registered the section that taught by the instructor and the student ’s advisor is the instructor. For each pair as such , following information should be listed:
Name of the student
Name of the Instructor
Find the students who have passed exams of all the courses opened by the department the students are enrolled in. For each student as such , following information should be listed:
name of the student
name of the department which student is enrolled in
Get information of 6th to 10th students according to the sorting rule that order students by students’ id ascending. For each student as such , following information should be listed:
id of the student
name of the student
Find students that has failed exam records that have no corresponding pass ones. For each student as such, following information should be listed:
id of the student
Name of the student
Count of courses that still have failed exam records un-overwrited.
Find students that has taked some courses more than one time. For each student as such, following information should be listed:
id of the student
Name of the student
ID of the course
The times of the student taking the course
Count of the failed exam records of the student on the course.
最后更新于