SQL

SQL

SQL查询语言概览

SQL数据定义

SQL查询的基本结构

单关系查询

distinct

下面这段语句就能完成一个简单的单关系查询:

SELECT		NAME
FROM 		instructor;

而我们有时候的数据单拿一个属性出来,数据是会大量重复的,比如我们执行下列语句:

SELECT		dept_name
FROM 		instructor;

就会出现大量的重复。

在关系模型的数学定义中,我们不允许关系里有重复的元素。但在实践中,去重是一件非常耗时的事情。因此SQL的实现允许出现重复的数据。

我们也可以加入关键词distinct手动去重:

SELECT DISTINCT dept_name
FROM 			instructor;

在SQL中默认不去重,但我们也可以显式地表达不去重:

SELECT ALL	dept_name
FROM 		instructor;

这种写法可以,但没必要。只需要知道distinct即可。

运算符

元组的属性可以使用运算符进行运算:

SELECT		ID, NAME, dept_name, salary*1.1
FROM 		instructor;

它会将所有数据都显示成1.1倍。但实际上仅仅是显示而已,这种操作不会实际影响关系中的数据。

where

它与编程语言中的if十分相像,只不过表达方式稍稍有点区别:

SELECT		NAME
FROM 		instructor
WHERE		dept_name = 'Comp. Sci.' AND salary > 70000;

这是它的简单用法,想好好用好得知道where实际的操作是什么,一会会提及。

多关系查询

实现一个简单的多表查询:

SELECT		NAME, instructor.dept_name, building
FROM 		instructor, department
WHERE		instructor.`dept_name` = department.`dept_name`;

一个SQL查询的含义

实际上,一个SQL可以被理解成下面三步:

  1. 先是from子句,为列出的关系产生笛卡儿积。
  2. 在是where语句,挑选出符合条件的元祖
  3. 最后是select,输出指定的属性

假如这个多关系查询忘记写where,会产生一个非常大的无用数据集,因此,在使用多表查询的时候,一定不要忘记写where

自然连接

实现一个简单的自然连接:

SELECT		NAME, course_id
FROM 		instructor NATURAL JOIN teaches;

natural join

自然连接只考虑两个关系中都出现的属性上取值相同的元组对。

且对于from来说,instructor NATURAL JOIN teaches返回的结果是一个关系。

而自然连接也存在一些问题:很有可能会出现冲突的属性,或者是我们并不希望被合并的属性,被强行合并了:

SELECT		NAME, title
FROM 		instructor NATURAL JOIN teaches, course
WHERE		teaches.`course_id` = course.`course_id`;

--------------------------------------------------------------------------------------------------------------
SELECT 		NAME, title
FROM 		instructor NATURAL JOIN teaches NATURAL JOIN course;

这两段运行结果看起来是一样的,实际上结果并不相同,因为natural join合并了我们并不期望合并的属性。

join (…) using (…)

为保留natural join的优点SQL提供了一种解决方案:

SELECT		NAME, title
FROM 		(instructor NATURAL JOIN teaches) JOIN course USING (course_id);

使用join (…) using (…)结构,能够自己指定自然连接的属性,就不会出现冲突合并的情况

附加的基本运算

更名运算

实现一个简单的更名例子:

SELECT		NAME AS instructor_name, course_id
FROM 		instructor, teaches
WHERE		instructor.`ID` = teaches.`ID`;

它最方便的地方就是可以将长名字变成短名字,同时可以用于区分同关系的。

字符串运算

字符串运算对大小写敏感,它不同于SQL语句。并且SQL库中会有丰富的处理字符串的函数,例如大写,小写,去空格……

在其中,还有一种操作符like可以完成模糊查询:

  • %:匹配任意字符串
  • _:匹配任意一个字符串

一个简单的实现例子:

SELECT		dept_name
FROM 		department
WHERE		building LIKE '%Watson%';

有时候我们需要匹配%之类的符号,可以使用escape定义转义符:

同时也支持not like寻找不匹配项。

select子句

*代表所有属性

元组的显示次序

我们可以让结果对次序进行控制。实现一个简单的例子:

SELECT		NAME
FROM 		instructor
WHERE		dept_name = 'Physics'
ORDER BY	NAME;

order by 默认升序,我们可以给他指定顺序。用asc代表升序,desc代表降序。

SELECT		*
FROM 		instructor
ORDER BY	salary DESC, NAME ASC;

where子句

between and

between and可以用来表示范围

这段语句:

SELECT		NAME
FROM 		instructor
WHERE		salary <= 100000 AND salary >= 90000;

与下面这段查询结果相同:

SELECT		NAME
FROM 		instructor
WHERE		salary BETWEEN 90000 AND 100000;

并且可用not between

字典序比较

如果我们需要编写这么一段SQL:

SELECT		NAME, course_id
FROM 		instructor, teaches
WHERE		instructor.`ID` = teaches.`ID` AND dept_name = 'Biology';

可以被改写成下列形式(按字典序比较):

SELECT		NAME, course_id
FROM 		instructor, teaches
WHERE		(instructor.`ID`, dept_name) = (teaches.`ID`, 'Biology');

集合运算

posted @ 2020-04-27 23:46  Herman·H  阅读(433)  评论(0编辑  收藏  举报