花了几天的时间将《SQL基础教程》(第二版)看完了,就将上面一些易错的、重要的知识点总结了一下。
SQL语句及其分类
DDL数据定义语言
CREATE: 创建数据库和表等对象
DROP:删除数据库和表等对象
ALTER:修改数据库和表等对象的结构
DML数据操纵语言
SELECT:查询表中的数据
INSERT:向表中插入新数据
UPDATE:更新表中的数据
DELETE:删除表中的数据
DCL数据控制语言
COMMIT:确认对数据库中的数据进行的变更
ROLLBACK:取消对数据库中的数据进行的变更
GRANT:赋予用户操作权限
REVOKE:取消用户操作权限
使用汉语别名使用“ ”扩起来
先where查询出符合指定条件的记录,然后select选取指定的列
- - 行注释
/* */ 多行注释
含有NULL的运算结果全为NULL
比较运算符不等于: <>
字符‘2’大于‘12’,不同于数字,字符按照条目在字典中出现的顺序比较大小。
不能对NULL使用比较运算符,如果想要选取为NULL的数据可以使用IS NULL,相反的IS NOT NULL。
AND运算符优先级高于OR运算符,想要优先执行OR可以使用括号。
逻辑运算中除了真假还有第三种值— 不确定(UNKNOWN),当加入NULL时,条件判断也就变得异常复杂,因此数据库领域的有识之士达成了”尽量不使用NULL的共识”,这也就解释了为什么在创建表时会给某些列设置NOT NULL约束的原因。
聚合函数会对NULL以外的对象进行汇总。但是只有COUNT函数除外,使用COUNT(*)可以查出包含NULL在内的全部数据的行数。注意使用COUNT函数的结果会根据输入参数的不同而不同。若为COUNT(列名)得到的则是除了NULL之外的数据行数。
所有的聚合函数如果以列名为参数,在计算之前都将NULL过滤掉,因此当使用SUM(列名)计算含有NULL的数据列时,其结果不会是NULL。
关键字DISTINCT 删除重复值。因此想要计算值的种类时,可以在COUNT函数的参数中使用DISTINCT。
子句书写顺序 SELECT–>FROM–>WHERE–>GROUP BY–>HAVING–>ORDER BY
在GROUP BY子句中指定的列称为聚合键或者分组列。聚合键中包含NULL时,在结果中会以”不确定”行(空行)的形式表现出来。
SELECT语句执行的顺序FROM–>WHERE–>GROUP BY–>SELECT –>ORDER BY这与第14条说明的顺序不同,这是由于在SQL语句中,书写顺序和DBMS内部的执行顺序不同。注意这里是程序执行的顺序。执行顺序也会根据DBMS的不同而不同,这里只需要有一个大致印象,记住SELECT子句的执行顺序在GROUP BY之后,在ORDER BY之前就行。
使用GROUP BY子句时,SELECT子句中不能出现聚合键之外的列名,因为如果出现列A,那结果中当前类别只有一行,而如果这个类别对应的类A有两个数据,该显示谁呢?问题就在于聚合键与其他类并不一定是一对一的。
在GROUP BY子句中不能使用SELECT子句中定义的别名,因为GROUP BY先执行,参照第16条。
GROUP BY子句结果的显示是无序的。
只有SELECT,HAVING,ORDER BY子句中能够使用聚合函数。WHERE子句中不能使用聚合函数。
SELECT子句使用聚合函数时,子句中只能存在以下三种元素:
1) 常数
2)聚合函数
3)GROUP BY子句中指定的列名(聚合键)在“想要删除选择结果中的重复记录”时使用DISTINCT,在“计算汇总结果”时使用GROUP BY。
WHERE子句用于指定数据行(记录)的条件,HAVING子句用于指定分组的条件。注意WHERE子句不能使用聚合函数。
HAVING子句的构成要素:常数,聚合函数,GROUP BY子句中使用的列名,即聚合键。(参照第17条)
聚合键所对应的条件不应该写在HAVING子句中,而应该书写在WHERE子句中。其中一个理由与性能即执行速度有关。通常情况下为了得到相同的结果,讲条件写在WHERE子句中要比写在HAVING子句中的处理速度要快,返回结果所需的时间更短。
(续第24条)为什么写在WHERE子句中速度更快呢?
这需要从DBMS的内部运行机制来考虑。使用COUNT函数等对表中的数据进行聚合操作时,DBMS内部就会进行排序处理。排序处理是会大大增加机器负担的高负荷处理。因此只有尽可能的减少排序行数才能提高处理速度。通过WHERE子句指定的条件,由于排序之前就对数据进行了过滤,因此能够减少排序的数量。但HAVING子句是在排序之后才对数据进行分组的,因此需要排序的数目较多。未指定ORDER BY子句中排列顺序时会默认使用升序ASC(ascendent)排列,降序使用关键字DESC(descendent)
排序键中如果包含NULL时,会在开头或末尾进行汇总。
在ORDER BY子句中可以使用SELECT子句中未使用的列和聚合函数。
在ORDER BY子句中不要使用列编号。
INSERT语句的SELECT语句中,可以使用WHERE子句或者GROUP BY子句等任意SQL语法(但使用OERDER BY子句并不会产生任何效果)。
删除表使用DROP TABLE语句,删除表中的数据(记录)使用DELETE语句。
同时更新多列时,可以在UPDATE语句的SET子句中,使用逗号分隔更新对象的多个列。
事务是需要在同一个处理单元中执行的一系列更新处理的集合。
DBMS遵循四种特性:原子性(Atomicity)、一致性(Cinsisitency)、隔离性(Isolation)和持久性(Durability),即ACID特性。
表中存储的是实际数据,而视图中保存的则是从数据表中取出数据所使用的SELECT语句。
视图的优点:
1)由于视图无需保存数据,因此可以节省存储设备的容量
2)可以将频繁使用的语句保存为视图,这样就不用每次都重新书写。应该避免在视图的基础上创建视图。
使用视图时,有哪些限制?
1)定义视图时可以使用任意SELECT子句,但除了ORDER BY子句,因为视图和表一样,数据行都是没有顺序的。实际上,有些DBMS在定义视图时,可以使用ORDER BY子句,但这并不是通用的语法,因此在定义视图时,请不要使用ORDER BY子句。
2)视图和表需要同时更新,因此通过汇总得到的视图无法进行更新。子查询作为内层查询会首先执行。
标量子查询就是返回单一值的子查询。
在细分的组内进行比较时,需要使用关联子查询。
谓词就是返回真值(TRUE/FALSE/UNKNOWN)的函数。也就是说谓词也就是函数的一种。
LIKE的三种使用方法:
1)前方一致
选取出作为查询条件的字符串与查询对象字符串起始部分相同的记录查询方式。比如 LIKE ‘ddd%’,查询起始字符含有ddd的字符串
2)中间一致
选取出查询对象字符串中含有作为查询条件的字符串的记录查询方式。无论该字符串出现在对象字符串的前面、中间、还是后面都没关系。如LIKE ‘%ddd%’
3)后方一致
与前方一致相反,选取出作为查询条件的字符串与查询对象字符串末尾部分相同的记录查询方式。比如 LIKE ‘%ddd’,查询末尾字符含有ddd的字符串%表示任意个字符,-表示任意一个字符。
BETWEEN的特点是选取的结果会包含两边的临界值。如果不想包含就可以使用<>。
为了选出某些值为NULL的列的记录,不能使用=,而只能使用特定的谓词IS NULL
谓词IN 和 NOT IN是无法选出NULL数据的。
通常指定关联子查询作为EXIST的参数。
EXIST只关心子查询中的记录是否存在,返回哪些列都没有关系。因此可以使用WHERE EXISTS (SELECT * FROM 。。WHERE。。 )
CASE表达式中的END不能省略。
表的加减法:UNION(并集)、INTERSECT(交集)、EXCEPT(差集)
注意:Oracle使用MINUS代替EXCEPT,MYSQL还不支持EXCEPT,因此也无法使用。使用UNION时会自动滤除重复的记录。要想保留重复记录,只需要在UNION后面添加关键字ALL就可以啦。
联结(JOIN)就是将其他表中的列添加过来,进行“添加列”的集合运算。UNION是以行为单位进行操作,而联结是以列为单位进行的
进行内联结时必须使用ON子句,并且要书写在FROM和WHERE之间
COALESCE 将NULL转换为其他值。