SQL是结构化查询语言(Structure Query Language)的缩写,它是使用关系模型的数据库(RDBMS)应用语言。html
在1970年代初,由IBM公司San Jose,California研究实验室的Edgar Frank Codd(又称Ted Codd)发表将数据组成表格的应用原则(Codd's Relational Algebra)。1974年,同一实验室的D.D.Chamberlin和R.F. Boyce对Codd's Relational Algebra在研制关系数据库管理系统System R中,研制出一套规范语言-SEQUEL(Structured English Query Language),并在1976年11月的IBM Journal of R&D上公布新版本的SQL(叫SEQUEL/2)。1980年更名为SQL。
1979年ORACLE公司首先提供商用的SQL,IBM公司在DB2和SQL/DS数据库系统中也实现了SQL。 1
Ted Codd是绝对的数据库开创者,以relation model
得到1981年图灵奖。咱们在关系模型中的Boyce-Codd Normal From
(介于第三范式和第四范式)也来自于他的名字。mysql
System R
在数据库历史上也绝对的重要。特别是看书的时候不断被提起。sql
1986年10月,美国ANSI采用SQL做为关系数据库管理系统的标准语言(ANSI X3. 135-1986),后为国际标准化组织(ISO)采纳为国际标准。
1989年,美国ANSI采纳在ANSI X3.135-1989报告中定义的关系数据库管理系统的SQL标准语言,称为ANSI SQL 89,该标准替代ANSI X3.135-1986版本。该标准为下列组织所采纳:
国际标准化组织(ISO),为ISO 9075-1989报告“Database Language SQL With Integrity Enhancement”
美国联邦政府,发布在The Federal Information Processing Standard Publication(FIPS PUB)127
当前,全部主要的关系数据库管理系统支持某些形式的SQL,大部分数据库至少遵照ANSI SQL89标准。
ANSI SQL92标准在交叉链接(cross join)和内部链接之上,新增长了外部链接,并支持在FROM子句中写链接表达式。支持集合的并运算、交运算。支持Case (SQL)表达式。支持CHECK约束。建立临时表。支持cursor。
支持事务隔离。 1
咱们这一篇文章采用PostgreSQL的SQL语法。重点咱们关注select...from...where
这种读操做,分析query (analytical query)。
数据集在 https://hyper-db.de/interface... 能够直接使用。另外在这个网页不容许进行写操做:insert
, update
, delete
之类的transactional query。固然create table
和drop table
也不被容许。数据库
架构 Schema: api
下载:
https://db.in.tum.de/teaching...架构
Schma和大部分SQL语句来自Prof. Alfons Kemper, Ph.D.的课件和书。spa
课件:3d
书: https://db.in.tum.de/teaching...code
select persnr, name from professoren where rang = 'C4'
select persnr, name, rang from professoren order by rang desc, name asc
select distinct rang from professoren
select p.name, v.titel from professoren p, vorlesungen v where p.persnr = v.gelesenvon and titel = 'Maeeutik'
select s.name, v.titel from studenten s, hoeren h, vorlesungen v where s.matrnr = h.matrnr and h.vorlnr = v.vorlnr
(select name from assistenten) union (select name from professoren)
-- correlated sub-query select p.name from professoren p where not exists( select * from vorlesungen v where v.gelesenvon = p.persnr ) -- un-correlated sub-query -- not in: 集合的比较 select p.name from professoren p where p.persnr not in ( select v.gelesenvon from vorlesungen v )
-- correlated sub-query select s.name from studenten s where not exists( select * from hoeren h where h.matrnr = s.matrnr ) -- un-correlated sub-query -- not in: 集合的比较 select s.name from studenten s where s.matrnr not in ( select h.matrnr from hoeren h )
select s.name from studenten s where s.semester >= all ( select semester from studenten )
select avg(semester) from studenten
select v.gelesenvon, sum(v.sws) from vorlesungen v group by v.gelesenvon
select v.gelesenvon, p.name, sum(v.sws) from vorlesungen v, professoren p where v.gelesenvon = p.persnr and rang = 'C4' group by v.gelesenvon, p.name having avg(v.sws) >= 3
这里须要注意一下aggregation operation。
对每个group都会生成一个tuple。因此对于带有group by
子句的SQL
语句,select
子句里面只能是group by
子句提到的属性值和aggregation operation。orm
SELECT * FROM studenten WHERE semester >= 1 AND semester <= 4; SELECT * FROM studenten WHERE semester between 1 and 4; SELECT * FROM studenten WHERE semester in (1,2,3,4);
SELECT * FROM studenten WHERE name like 'T%eophrastos'; SELECT DISTINCT s.name FROM vorlesungen v, hoeren h, studenten s WHERE s.matrnr = h.matrnr AND h.vorlnr = v.vorlnr AND v.titel LIKE '%thik%';
case
:SELECT matrnr, (case when note <= 1.5 then 'sehr gut' when note <= 2.5 then 'gut' when note <= 3.5 then 'befriedigend' when note <= 4.0 then 'ausreichend' else 'nicht bestanden' end) FROM pruefen;
left outer join
:SELECT p.persnr, p.name, f.persnr, f.note, f.matrnr, s.matrnr, s.name FROM professoren p left outer join pruefen f left outer JOIN studenten s ON f.matrnr = s.matrnr ON p.persnr = f.persnr;
right outer join
:SELECT p.persnr, p.name, pf.persnr, pf.note, pf.matrnr, s.matrnr, s.name FROM professoren p right outer JOIN pruefen pf right outer JOIN studenten s ON pf.matrnr = s.matrnr ON p.persnr = pf.persnr;
full outer join
:SELECT p.persnr, p.name, pf.persnr, pf.note, pf.matrnr, s.matrnr, s.name FROM professoren p full outer JOIN pruefen pf full outer JOIN studenten s ON pf.matrnr = s.matrnr ON p.persnr = pf.persnr;