阅后简记
第一章 数据库和SQL
1-1 数据库是什么
数据库(Database,DB)是将大量数据保持起来,通过计算机加工而成的可以进行高效访问的数据集合。
数据库管理系统(Datebase Management System,DBMS)用来管理数据库的计算机系统称为数据库管理系统。
DBMS种类:
层次型数据库(Hierarchical Database,HDB):最古老的数据库之一,把数据通过层次结构(木结构)的方式表现出来。
关系型数据库(Relational Fatabase,RDB):采用行列二维表结构来管理数据,其代表有Oracle Database、SQL Server、DB2、PostgreSQL、MySQL。
面向对象数据库(Object Oriented Database,OODB):把数据及对数据操作集合起来以对象为单位进行管理。
XML数据库(XML Database,SMLBD):XML作为网络上进行数据交互传输,可以对XML形式的大量数据进行高速处理。
键值存储系统(Key-Valus Store,KVS):单纯用来保持查询所使用的主键(Key)和值(Value)组合的数据库。
1-2 数据库结构
RDBMS常见系统结构就是客户端/服务器(C/S类型)。
表:用来管理数据的二维表在关系数据库中简称为表。
法则1-1 关系数据库以行为单位读写数据。
法则1-2 一个单元格只能输入一个数据。
法则1-3 学会标准的SQL就可以在各种RDBMS中书写SQL语句。
1-3 SQL概要
SQL是为操作数据库而开发的语言。
原则上SQL语句都会使用分号结尾。
SQL根据操作目的分可以分为DDL、DML和DCL。
DDL(Data Definition Language,数据定义语言):用来创建或者删除存储数据用的数据库以及数据库中表等对象。
DDL包含以下几种指令:
CREATE:创建数据库和表等对象
DROP:删除数据库和表等对象
ALTER:修改数据库和表等对象的结构
DML(Data Manipulation Language,数据操作语言):用来查询或者变更表中的记录。
DML包含以下几种指令:
SELECT:查询表中的数据
INSERT:向表中插入新数据
UPDATE:变更表中的数据
DELETE:删除表中的数据
DCL(Data Control Language,数据控制语言);用来确认或者取消对数据库中的数据进行变更。
DCL包含以下几种指令:
COMMIT:确认对数据库中的数据进行变更
ROLLBACK:取消对数据库中的数据进行变更
GRANT:赋予用户操作权限
REVOKE:取消用户的操作权限
法则1-4 SQL根据功能不同可以分为三类,其中使用最多的是DML
SQL的基本书写规则:
法则1-5 SQL语句要以分号(;)结尾。
法则1-6 关键字不区分大小写,数据区分大小写。
法则1-7 字符串和日期需要使用单引号(‘)括起来
法则1-8 单词之间需要使用半角空格或者换行进行分割。
1-4 表的创建
表通过 CREATE TABLE 语句创建而成。
表和列命名要使用有意义的文字。
指定列的数据类型(整数型、字符型和日期型等)。
可以在表中设置约束(主键约束和 NOT NULL 约束等)。
语法1-1 创建数据库的CREATE TABLE 语句
CREATE DATABASE <数据库名称>;
示例1-1 创建数据库 shop 的 CREATE DATABASE 语句创建而成。
CREATE DATABASE shop;
语法1-2 创建表的 CREATE TABLE 语句
CREATE TABLE <表名>
(<列名1><数据类型><该列所需约束>;
<列名2><数据类型><该列所需约束>;
<列名3><数据类型><该列所需约束>;
<列名4><数据类型><该列所需约束>;
……
<该表的约束1>,<该表的约束2>,……);
示例1-2 创建 shohin 表的 CREATE TABLE 语句
CREATE TABLE shohin
(shohin_id char(4) NOT NULL,
 shohin_mei VARCHAR(100) NOT NULL,
 shohin_bunrui VARCHAR(32) NOT NULL,
 hanbai_tanka INTEGER,
 shiire_tanka INTEGER,
 torokubi DATE,
 PRIMARY KEY (shohin_id));
命名规则
法则1-9 数据库名称、表名和列名等可以使用半角英文字母、半角数字、下划线_。
法则1-10 名称必须以半角英文字母开头。
法则1-11 名称不能重复(同数据库中不能有两个相同名称的表,同表中不能有两个相同名称的列)。
数据类型的指定:
INTEGER 型:用来指定存储整数的列的数据类型(数字型),不能存储小数
CHAR 型:用来指定存储字符串的列的数据类型(字符型),在括号中指定该列可以存储的字符串的最大长度,超过最大长度无法输入到该列。固定长度,输入数据长度不足指定长度的部分用 NULL 值保持
VARCHAR 型:用来指定鵆字符串的列的数据的类型(字符串类型),以颗便长字符串保持字符串。
特定:Oracle 中使用 VARCHAR2 型
DATE 型:用来指定存储日期(年月日)的列的数据类型(日期型)。
特定 SQL:除了年月日之外,Oracle 中使用的 DATE 型还包含时分秒。
约束的设置:对列中存储的数据进行限制或者追加条件的功能。
NOT NULL:非空约束:不能为空
PRIMARY KEY:主键约束:不能重复
1-5 表的删除和更新
使用 DROP TABLE 语句来删除表
使用 ALTER TABLE 语句向表中添加列或者从表中删除列;
语法1-3 删除表时使用的 DROP TABLE 语句
DROP TABLE <表名>;
示例1-3 删除shohon表
DROP TABLE shohin;
法则1-12 删除的表无法恢复的,指定 DROP TABLE 语句之前务必仔细确认;
表定义的更新(ALTER TABLE 语句)
语法1-4 添加列的 ALTER TABLE 语句
ALTER TABLE <表名> ADD COLUMN <列的定义>;
特定 SQL:
Oracle 和 SQL Server 中不用写 COLUMN。
ALTER TABLE <表名> ADD <列名>;
Oracle 中添加多列
ALTER TABLE <表名> ADD (<列名>,<列名>,……);
示例1-4 添加一列可以存储100位可变长度字符串的 shohin_mei_kana 列
DB2、PostgreSQL、MySQL
ALTER TABLE shohin ADD COLUMN shohin_mei_kana VARCHAR(100);
Oracle
ALTER TABLE shohin ADD (shohin_mei_kana VARCHAR2(100));
SQL Server
ALTER TABLE shohin ADD shohin_mei_kana VARCHAR(100);
语法1-5 删除列的 ALTER TABLE 语句
ALTER TABLE <表名> DROP COLUMN <列名>;
特定 SQL:
Oracle 和 SQL Server 中不用写 COLUMN.
ALTER TABLE <表名> DROP <列名>;
Oracle 同时删除多列
ALTER TABLE <表名> DROP (<列名>,<列名>,……);
示例1-5 删除 shohin_mei_kana 列
SQL Server、DB2、PostgreSQL、MySQL。
ALTER TABLE shohin DROP COLUMN shohin_mei_kana;
Oracle
ALTER TABEL shohin DROP (shohin_mei_kana);
法则1-13 表定义变更之后无法恢复,在执行 ALTER TABLE 语句之前请务必仔细确认。
向 shohin 表中插入数据
示例1-6 向 shohin 表中插入数据的 SQL 语句
特定 SQL:
SQL Server、PostgreSQL
BEGIN TRANSACTION;--开始插入行的指令语句
INSERT INTO shohin VALUES('0001','T恤衫','衣服',1000,500,'2009-09-20');
COMMIT;--确认插入行的指令语句
MySQL
START TRANSACTION;
INSERT INTO shohin VALUES('0001','T恤衫','衣服',1000,500,'2009-09-20');
COMMIT;
Oracle、DB2
INSERT INTO shohin VALUES('0001','T恤衫','衣服',1000,500,'2009-09-20');
COMMIT;
示例1-A 变更表名
特定SQL:
Oracle、PostgreSQL
ALTER TABLE sohin RENAME TO shohin;
DB2
RENAME TABLE sohin TO shohin;
SQL Server 
sp_rename 'sohin','shohin';
MySQL
RENAME TABLE sohin to shohin;
第二章 查询基础
2-1 SELECT 语句基础
使用 SELECT 语句从表中选取数据。
为列设定显示用的别名。
SELECT 语句中可以使用常数或者表达式。
通过指定 DISTINCT 可以删除重复的行。
SQL 语句中可以使用注释。
可以通过 WHERE 语句从表中选取出符合查询条件的数据。
列的查询
语法2-1 基本的 SELECT 语句
SELECT <列名>,……
FROM <表名>;
SELECT 子句列举从表中查询出列的名称,FROM 子句指定了选取出数据的表的名称。
示例2-1 从 shohin 表中输出3列
SELECT shohin_id,shohin_mei,shiire_tanka
FROM shohin;
查询多列时,需要使用逗号进行分隔排列。
查询出表中的所有列
语法2-2 查询全部的列
SELECT *
FROM <表名>;
示例2-2 输出 shohin 表中全部的列
SELECT * FROM shohin;
示例2-3 与示例2-2具有相同含义的SELECT 语句
SELECT shohin_id,shohin_meo,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi
FROM shohin;
法则2-1:星号(*)代表全部列的意思。
为列设定别名
示例2-4 为列设定别名
SELECT shohin_id AS id,
       shohin_mei AS namae,
       shohin_tanka AS tanka,
FROM shohin;
示例2-5 设定汉语别名
SELECT shohin_id AS "商品编号",
       shohin_mei AS "商品名称",
       shohin_tanka AS "进货单价",
FROM shohin;
法则2-2 设定汉语别名时需要使用双引号(")括起来。
常数的查询
示例2-6 查询常数
SELECT '' AS mojiretsu, 38 AS kazu, '2009-02-24' AS hizuke
FROM shohin;
从结果中删除重复行
示例2-7 使用 DISTINCT 删除 shohin_bunrui 列中重复的数据
SELECT DISTINCT shohin_bunrui
FROM shohin;
法则2-3 在 SELECT 语句中使用 DISTINCT 可以删除重复行。
示例2-8 对含有 NULL 数据的列使用 DISTINCT 关键字
SELECT DISTINCT shiire_tanka
FROM shohin;
在使用 DISTINCT 时,NULL 也被视为一类数据。
示例2-9 在多列之前使用 DISTINCT
SELECT DISTINCT shohin_bunrui,torokubi
FROM shohin;
根据 WHERE 语句来选择记录
语法2-3 SELECT语句中的 WHERE 子句
SELECT <列名>,……
FROM <表名>
WHERE<条件表达式>;
示例2-10 用来选取 shohin_bunrui 列为“衣服”的记录的 SELECT 语句
SELECT shohin_mei,shohin_bunrui
FROM shohin
WHERE shohin_bunrui = '衣服';
示例2-11 也可以不选取作为查询条件的列
SELECT shohin_mei
FROM shohin
WHERE shohin_bunrui = '衣服';
示例2-12 随意改变子句的书写顺序会造成错误
SELECT shohin_mei,shohin_bunrui
WHERE shohhin_bunrui = '衣服'
FROM shohin;--报错
法则2-4 WHERE 子句要紧跟在 FROM 子句之后。
注释的书写方法
一行注释:书写在’--‘之后,只能写在同一行。
多行注释:书写在“/*”和“*/”之间,可以跨多行。
示例2-13 1行注释的例子
-- 本 SELECT 语句用来除以结果中的重复数据
SELECT DISTINCT shohin_id,shiire_tanka
FROM shohin;
示例2-14 多行注释的例子
/* 本 SELECT 语句,
   用来除以结果中的重复数据.*/
SELECT DISTINCT shohin_id,shiire_tanka
FROM shohin;
示例2-15 在SQL语句中插入1行注释
SELECT DISTINCT shohin_id,shiire_tanka
-- 本 SELECT 语句用来除以结果中的重复数据
FROM shohin;
示例2-16 在 SQL 语句中插入多行注释
SELECT DISTINCT shohin_id,shiire_tanka
/*本 SELECT 语句,
   用来除以结果中的重复数据。*/
FROM shohin;
法则2-5 注释是 SQL 语句中用来标识说明或者注意事项的部分,分1行注释和多行注释。
2-2 算术运算符和比较运算符
运算符就是对其两边的列或者值进行运算(计算或者大小比较等)的符号
使用算术运算符可以进行四则运算
括号可以提升运算的优先顺序
包含 NULL 的运算,结果也是 NULL
比较运算符可以用来判断列或者值是否相等,还可以用来比较大小。
判断是否为 NULL,需要使用 IS NULL 或者 IS NOT NULL 运算符
算术运算符
示例2-17 SQL 语句中也可以使用运算表达式
SELECT shohin_mei,hanbai_tanka,
       hanbai_tanka * 2 AS "banbai_tnaka_x2"
FROM shonin;
四则运算:加、减、乘、除
法则2-6 SELECT 子句可以使用常数或者表达式。
需要注意 NULL
比较运算符
示例2-18 选取出 hanbai_tanka 列为500的记录
SELECT shohin)mei,shohin_bunrui
FROM shohin
WHERE hanbai_tanka = 500;
示例2-19 选取出 hanbai_tanka 列的值不是500的记录
SELECT shohin_mei,shohin_bunrui
FROM shohin
WHERE hanbai_tanka <> 500;
比较运算符:等于、不等于、大于等于、小于等于、大于、小于。
示例2-20 选取出销售单价大于等于1000元的记录
SELECT shohin_mei,shohin_bunrui,hanbai_tanka
FROM shohin
WHERE hanbai_tanka >= 1000;
法则2-7 使用比较运算符时一定要注意不等号和等号的位置。
示例2-22 WHERE 子句的条件表达式中也可以使用计算表达式
SELECT shohin_mei,hanbai_tanka,shiire_tanka
FROM shohin
WHERE hanbai_tanka - shiire_tanka >= 500;
对字符串使用不等号时的注意事项
示例2-24 选取出大于'2'的数据的 SELECT 语句
SELECT chr
FROM Chars
WHERE chr > '2';--字符串的大小,按 AScll 码排序
法则2-8 字符串类型的数据原则上按照字典顺序进行排序。不能与数字大小顺序混淆。
不能对 NULL 使用比较运算符
示例2-28 选取 NULL 的记录
SELECT shohin_mei,shiirt_tanka
FROM shohin
WHERE shiire_tanka IS NULL;
示例2-29 选取不为NULL的记录
SELECT shohin_mei,shiirt_tanka
FROM shohin
WHERE shiire_tanka IS NOT NULL;
法则2-9 希望选取 NULL 记录时,需要在条件表达式中使用 IS NULL 运算符。希望选择不是 NULL 记录时,需要在条件表达式中使用 IS NOT NULL 运算符。希望选择不是 NULL 记录时,需要在条件表达式中使用 IS NOT NULL 运算符
2-3 逻辑运算符
通过使用逻辑运算符,可以将多个查询条件进行组合。
通过 NOT 运算符可以作为"不是"这样的查询条件。
两边条件都成立时,使用AND运算符的查询条件才成立。
值可以归结为真(TRUE)和假(FALSE)其中之一的值称为真值。比较运算符比较成立时返回真,不成立时返回假。但是,在 SQL 中还存在另外一个特定的真值,不确定(UNKNOWN)
根据逻辑运算符对真值进行的操作和其结果归结为的表称之真值表。
SQL 中的逻辑运算是包含对真、假和不确定进行运算的三值逻辑。
NOT 运算符
示例2-30 选取出销售单价大于等于1000元的记录
SELECT shohin_mei, shohin_bunrui,hanbai_tanka
FROM shohin
WHERE haibai_tanka >= 1000;
示例2-31 向示例2-30 的查询条件中添加 NOT 运算符
SELECT shohin_mei, shohin_bunrui,hanbai_tanka
FROM shohin
WHERE NOT haibai_tanka >= 1000;
示例2-32 WHERE 子句的查询条件和示例2-31 中的查询条件是等价的
SELECT shohin_mei,shohin_bunrui
FROM shohin
WHERE hanbai_tanka < 1000;
法则2-10 NOT 运算符用来否定某一条件,但是不能滥用。
AND 运算符和 OR 运算符
在 WHERE 子句中使用AND运算符或者OR运算符,可以对多个查询条件进行组合。
AND 运算符在其两侧的查询条件都成立时整个查询条件才成立。其意思相当于“并且”
OR 运算符在其两侧的查询条件中有一个成立时整个查询条件都成立。其意思相当于“或者”。
示例2-33 在 WHERE 子句的查询条件中使用 AND 运算符
SELECT shohin_mei,shiire_yanka
FROM shohin
WHERE shohin_bunrui = '厨具用具'
AND hanbai_tanka >= 3000;
示例2-34 在 WHERE 子句的查询条件中使用 OR 运算符
SELECT shohin_mei,shiire_tanka
FROM shohin
WHERE shohin_bunrui = '厨具用具'
OR hanbai_tanka >= 3000;
法则2-11 多个查询条件进行组合时,需要使用 AND 运算符或者 OR 运算符。
法则2-12 文氏图很方便。
使用括号强化处理
示例2-35 将查询条件原封不动地写入条件表达式
SELECT shohin_mei,shiire_tanka,torokubi
FROM shohin
WHERE shohin_bunrui = '办公用品'
AND torokubi = '2009-09-11'
OR torokubi  = '2009-09-20';--AND运算优先于OR运算执行
示例2-36 通过括号让 OR 运算先于 AND 运算执行
SELECT shohin_mei,shiire_tanka,torokubi
FROM shohin
WHERE shohin_bunrui = '办公用品'
AND (torokubi = '2009-09-11'
OR torokubi  = '2009-09-20');
法则2-13 AND 运算符的优先级高于 OR 运算符。想要优先执行 OR 运算时可以使用括号。
逻辑运算符和真值
逻辑运算符对比较运算符等返回的真值进行操作。
法则2-14 通过创建真值表,无论多复杂的条件,都会更容易理解。
含有 NULL 时的真值
三值逻辑
第三章 聚合与排序
3-1 对表进行聚合查询
使用聚合函数对表中的列进行合计值或者平均值等合计操作。
通常,聚合函数会对NULL以外的对象进行合计。但是只有 COUNT 函数例外,使用 COUNT(*) 可以查出包含 NULL 在内的全部数据行数。
使用 DISTINCT 关键字删除重复值。
聚合函数
通过 SQL 对数据进行某种操作或计算时需要使用函数。
COUNT():计算表中的记录数(行数).
SUM():计算表中数值列的数据合计值。
AVG():计算表中数值列的数据平均值。
MAX():求出表中任意列中数据的最大值。
MIN():求出表中任务列中数据的最小值。
计算表中数据的行数
示例3-1 计算全部数据行数
SELECT COUNT(*)
FROM shohin;
计算 NULL 以外数据的行数
示例3-2 计算 NULL 之外的数据行数
SELECT COUNT(shiire_tanka)
FROM shohin;
示例3-3 将包含 NULL 的列作为参数时,COUNT(*)和 COUNT(<列名>)的结果并不相同
SELECT COUNT(*),COUNT(col_1)
FROM Nulltb1;
法则3-1 COUNT 函数的结果根据参数的不同而不同。COUNT(*)会得到包含NULL的数据行数,而 COUNT(<列名>)会得到 NULL 之外的数据行数。 
计算合计值
示例3-4 计算销售单价的合计值
SELECT SUM(hanbai_tanka)
FROM shohin;
示例3-5 计算销售单价和进货单价的合计值
SELECT SUM(hanbai_tanka),SUM(shiire_tanka)
FROM shohin;
法则3-2 聚合函数会将 NULL 排除在外。但 COUNT(*)例外,并不会排除 NULL 。
计算平均值
示例3-6 计算销售单价的平均值
SELECCT AVG(hanbai_tanka)
FROM shohin;
示例3-7 计算销售单价和进货单价的平均值
SELECCT AVG(hanbai_tanka),AVG(shiire_tanka)
FROM shohin;
计算最大值和最小值
示例3-8 计算销售单价的最大值和进货单价的最小值
SELECCT MAX(hanbai_tanka),MIN(shiire_tanka)
FROM shohin;
示例3-9 计算登记日期的最大值和最小值
SELECCT MAX(torokubi),MIN(torokubi)
FROM shohin;
法则3-3 MAX / MIN 函数几乎适用于所有数据类型的列。SUM / AVG 函数只适用于数值类型的列。
使用聚合函数删除重复值(关键字 DISTINCT )
示例3-10 计算去除重复数据后的数据行数
SELECT COUNT(DISTINCT shohin_bunrui)
FROM shohin;
示例3-11 先计算数据行数再删除重复数据的结果
SELECT DISTINCT COUNT(shohin_bunrui)
FROM shohin;
法则3-4 想要计算值的种类时,可以在 COUNT 函数的参数中使用 DISTINCT。
示例3-12 使不使用 DISTINCT 时的动作差异( SUM 函数)
SELECT SUM(hanbai_tanka),SUM(DISTINCT hanbai_tanka)
FROM Shohin;
法则3-5 在聚合函数的参数中使用 DISTINCT,可以删除重复数据。
3-2 对表进行分组
使用 GROUP BY 子句可以像切蛋糕那边将表进行分割。通过使用聚合函数和 GROUP BY 子句,可以根据“商品种类“或者”登记日期“等将表分割后再进行聚合。
聚合键中包含 NULL 时,在结果中会以”不确定“行(空行)的形式表现出来。
使用聚合函数和 GROUP BY 子句时需要注意以下4点:1.只能写在 SELECT 子句中;2.GROUP BY 子句中不能使用 SELECT 子句中列的别名;3.GROUP BY 子句的聚合结果时无序的;4.WHERE 子句中不能使用聚合函数.
GROUP BY 子句
语法3-1 使用GROUP BY 子句进行聚合
SELECT <列名1>,<列名2>,<列名3>,……
FROM <表名>
GROUP BY <列名1>,<列名2>,<列名3>,……;
示例3-13 按照商品种类统计数据行数
SELECT shohin_bunrui,COUNT(*)
FROM shohin
GROUP BY shohin_bunrui;
法则3-6 GROUP BY 就像是切分表的一把刀。
法则3-7 SQL 子句的顺序不能改变,也不能互相替换。
聚合键中包含 NULL 的情况
示例3-14 按照进货单价统计数据行数
SELECT shiire_tanka,COUNT(*)
FROM shohin
GROUP BY shiire_tanka;
法则3-8 聚合键中包含 NULL 时,在结果中会以”不确定“行(空行)的形式表现出来。
使用 WHERE 子句时 GROUP BY 的执行结果
语法3-2 使用 WHERE 子句和 GROUP BY 子句进行聚合处理
SELECT <列名1>,<列名2>,<列名3>,……
FROM <表名>
WHERE
GROUP BY <列名1>,<列名2>,<列名3>,……;
示例3-15 同时使用 WHERE 子句和 GROUP BY 子句
SELECT shiire_tanka,COUNT(*)
FROM shohin
WHERE shohin_bunrui = '衣服'
GROUP BY shiire_tanka;
与聚合函数和 GROUP BY 子句有关的常见错误
常见错误1 使用聚合函数时,在 SELECT 子句中书写了多余的列,只能存在以下三种元素:常数、聚合函数、GROUP BY 子句中指定的列名。
示例3-16 在 SELECT 子句中书写聚合键之外的列名会发生错误
SEECT shohin_mei,shiire_tanka,COUNT(*)
FROM shohin
GROUP BY shiire_tanka;--报错
法则3-9 使用 GROUP BY 子句时,SELECT 子句中不能出现聚合键之外的列名。
常见错误2 在 GROUP BY 子句中写了列的别名
示例3-17 GROUP BY 子句中使用列的别名会引发错误
SELECT shohin_bunrui AS sb,COUNT(*)
FROM shohin
GROUP BY sb;
法则3-10 在 GROUP BY 子句中不能使用 SELECT 子句中定义的别名。
常见错误3 GROUP BY 子句的结果能排序吗?
随机的
法则3-11 GROUP BY 子句结果的显示是无序的。
常见错误4 在 WHERE 子句中使用聚合函数
示例3-18 按照商品种类统计数据行数
SELECT shohin_bunrui,COUNT(*)
FROM shohin
GROUP BY shohin_bunrui;
示例3-19 在 WHERE 子句中使用聚合函数会引发错误
SELECT shohin_bunrui,COUNT(*)
FROM shohhihn
WHERE COUNT(*) = 2
GROUP BY shohin_bunrui;--报错
法则3-12 只有 SELECT 子句和 HAVING 子句(以及 ORDER BY 子句)中能够使用聚合函数。
示例3-A DISTINCT 和 GROUP BY 能够实现相同的功能
SELECT DISTINCT shohin_bunrui
FRON shohin;

SELECT shohin_bunrui
FROM shohin
GROUP BY shhohin_bunrui;
3-3 为聚合结果指定条件
使用 COUNT 函数等对表中数据进行聚合操作时,为其指定条件的不是 WHERE 子句,而需要使用 HAVING 子句。
聚合函数可以在 SELECT 子句、HAVING 子句和 ORDER BY 子句中使用。
HAVING 子句要写在 GROUP BY 子句之后。
WHERE 子句用来指定数据行的条件,HAVING 子句用来指定分组的条件。
HAVING 子句
语法3-3 HAVING 子句
SELECT <列名1>,<列名2>,<列名3>,……
FROM <表名>
GROUP BY <列名1>,<列名2>,<列名3>,……
HAVING <分组结果对应的条件>;
法则3-13 HAVING子句要写在 GROUP BY 子句之后。
示例3-20 从通过商品种类进行聚合分组后的结果中,取出”包含数据的行数为2行“的组
SELECT shohin_bunrui,COUNT(*)
FROM shohin
GROUP BY shohin_bunrui
HAVING COUNT(*) = 2;
示例3-31 不使用 HAVING 子句的情况
SELECT shohin_bunrui,COUNT(*)
FROM shohin
GROUP BY shohin_bunrui;
示例3-22 不使用 HAVING 子句的情况
SELECT shohin_bunrui,AVG(hanbai_tanka)
FROM shohin
GROUP BY shohin_bunrui;
示例3-23 使用 HAVING 子句设定条件的情况
SELECT shohin_bunrui,AVG(hanbai_tanka)
FROM shohin
GROUP BY shohin_bunrui
HAVING AVG(hanbai_tanka) >= 2500;
HAVING 子句的构成要素
HAVING 子句和包含 GROUP BY 子句时的 SELECT 子句一样,能够使用的3种要素如下:常数、聚合函数、GROUP BY 子句中指定的列名。
示例3-24 HAVING 子句的不正确使用方法
SELECT shohin_bunrui,COUNT(*)
FROM shohin
GROUP BY shohin_bunrui
HAVING shohin_mei = '圆珠笔';
相对于 HAVING 子句,要适合写在WHERE子句中的条件
示例3-25 将条件书写在 HAVING 子句的情况
SELECT shohin_bunrui,COUNT(*)
FROM shohin
GROUP BY shohin_bunrui
HAVING shouin_bunrui = '衣服';
示例3-26 将条件书写在 WHERE 子句的情况
SELECT shohin_bunrui,COUNT(*)
FROM shohin
WHERE shouin_bunrui = '衣服';
GROUP BY shohin_bunrui
WHERE 子句 = 指定行所对应的条件;
HAVING 子句 = 指定组所对应的条件;
法则3-14 聚合键所对应的条件不应该书写在 HAVING 子句当中,而应该书写在 WHERE 子句当中。
3-4 对查询结果进行排序
使用 ORDER BY 子句对查询结果进行排序
在 ORDER BY 子句中列名的后面使用关键字 ASC 可以进行升序排序,使用 DESC 关键字可以进行降序排序。
ORDER BY 子句中可以指定多个排序键。
排序键中包含 NULL 时,会在开头或末尾进行汇总。
ORDER BY 子句中可以使用 SELECT 子句中定义的列的别名.
ORDER BY 子句中可以使用 SELECT 子句中未出现的列或者聚合函数。
ORDER BY 子句中不能使用列的编号。
ORDER BY 子句
示例3-27 显示商品编号、商品名称、销售单价和进货单价的 SELECT 语句
SELECT shohin_id,shohin_mei,hanbai_tannka,shiire_tanka
FROM shohin;
语法3-4 ORDER BY 子句
SELECT <列名1>,<列名2>,<列名3>,……
FROM <表名>
ORDER BY <排序基准列1>,<排序基准列2>,……;
示例3-28 按照销售单价由低到高(升序)进行排序
SELECT shohin_id,shohin_mei,hanbai_tanka,shiire_tanke
FROM shohin
ORDER BY hanbai_tanka;
法则3-15 ORDER BY 子句通常写在 SELECT 语句的末尾。
指定升序或者降序
示例3-29 按照销售单价由高到地(降序)进行排序
SELECT shohin_id,shohin_mei,hanbai_tanka,shiire_tanke
FROM shohin
ORDER BY hanbai_tanka DESC;
法则3-16 未指定 ORDER BY 子句中排序顺序时会默认使用升序进行排列。
指定多个排序键
示例3-30 按照销售单价和商品编号的升序进行排序
SELECT shohin_id,shohin_mei,hanbai_tanka,shiire_tanke
FROM shohin
ORDER BY hanbai_tanka,shohin_id;
NULL的顺序
示例3-31 按照进货单价的升序进行排序
SELECT shohin_id,shohin_mei,hanbai_tanka,shiire_tanke
FROM shohin
ORDER BY shiire_tanka;
法则3-17 排序键中包含 NULL 时,会在开头或末尾进行汇总。
在排序键中使用显示用别名
示例3-32 ORDER BY 子句中可以使用列的别名
SELECT shohin_id AS id,shohin_mei,hanbai_tanka AS ht,shiire_tanke
FROM shohin
ORDER BY ht,id;
法则3-18 在 ORDER BY 子句中可以使用 SELECT 子句中定义的别名。
ORDER BY 子句中可以使用的列
示例3-33 SELECT 子句中未包含的列也可以在 ORDER BY 子句中使用。
SELECT shohin_mei,hanbai_tanka,shiire_tanke
FROM shohin
ORDER BY shohin_id;
示例3-34 ORDER BY 子句中也可以使用聚合函数
SELECT shohin_bunrui,COUNT(*)
FROM shohin
GROUP BY shohin_bunrui
ORDER BY COUNT(*);
法则3-19 在 ORDER BY 子句中可以使用 SELECT 子句中未使用的列和聚合函数。
不要使用列编号
示例3-35 ORDER BY 子句中可以使用列的编号
--使用列名
SELECT shohin_id,shohin_mei,hanbai_tanka,shiire_tanke
FROM shohin
ORDER BY hanbai_tanka DESC,shohin_id;
--使用列编号
SELECT shohin_id,shohin_mei,hanbai_tanka,shiire_tanke
FROM shohin
ORDER BY 3 DESC,1;
法则3-20 在 ORDER BY 不要使用列编号。
第四章 数据更新
4-1 数据的插入( INSERT 语句的使用方法)
使用 INSERT 语句可以向表插入数据(行)。原则上,INSERT 语句每次执行一行数据的插入。
列名和值用逗号隔开,分别括在()内,这种形式称为清单。
对表中所有列进行 INSERT 操作时可以省略表名后的列清单。
插入 NULL 时需要在 VALUES 子句的值清单中写入 NULL 。
可以为表中的列设定默认值(初始值)。默认值可以通过在 CREATE TABLE 语句中,为列设置 DEFAULT 约束来设定。
插入默认值可以通过两种方式实现,即在 INSERT 语句的 VALUES 子句中指定 DEFAULT 关键字(显示方法),或省略列清单(隐示方法)。
使用 INSERT…SELECT 可以从其他表中复制数据。
什么是 INSERT
用来装入数据的 SQL 就是 INSERT (插入)
示例4-1 创建 shohinIns 表的 CREATE TABLE 语句
CREATE TABLE shohinIns
(shohin_id CHAR(4) NOT NULL,
 shohin_mei VARCHAR(100) NOT NULL,
 shohin_bunrui VARCHAR(32) NOT NULL,
 hanbai_tanka INTEGER DEFAULT 0,
 shiire_tanka INTEGER,
 torokubi DATE,
 PRIMARY KEY (shohin_id));
INSERT语句的基础语法
语法4-1 INSERT 语句
INSERT INTO <表名>(列1,列2,列3,……)VALUES(值1,值2,值3,……);
示例4-2 向表中插入一行数据
INSERT INTO shohinIns(shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi)VALUES('0001','T恤衫','衣服',1000,500,'2009-09-20');
法则4-1 原则上,执行一次 INSERT 语句插入一行数据。
示例4-A 通常 INSERT 和多行 INSERT
--通常的 INSERT
INSERT INTO shohinIns VALUES('0002','打孔器','办公用品',500,320,'2009-09-11');
INSERT INTO shohinIns VALUES('0003','运动T恤','衣服',4000,2800,NULL);
--多行INSERT(Oralce以外的数据库)
INSERT INTO shohinIns VALUES('0002','打孔器','办公用品',500,320,'2009-09-11'),
                            ('0003','运动T恤','衣服',4000,2800,NULL);
列清单的省略
对表进行全列 INSERT 时,可以省略表后的列清单。
示例4-3 省略列清单
--包含列清单
INSERT INTO shohinIns(shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi)VALUES('0001','T恤衫','衣服',1000,500,'2009-09-20');
--省略列清单
INSERT INTO shohinIns VALUES('0001','T恤衫','衣服',1000,500,'2009-09-20');
插入 NULL
INSERT 语句中共享给某列赋予 NULL 值时,可以直接在 VALUES 子句的值清单在写入 NULL。
示例4-4 向 shiire_tanka 列中插入 NULL
INSERT INTO shohinIns(shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi)VALUES('0001','T恤衫','衣服',1000,NULL,'2009-09-20');
插入默认值
示例4-5 创建 shohinIns 表的 CREATE TABLE 语句(节选)
CREATE TABLE shohinIns
(shohin_id CHAR(4) NOT NULL,
 (略)
 hanbai_tanka INTEGER DEFAULT 0,
 (略)
 PRIMARY KEY (shohin_id));
通过显示方法插入默认值
在 VALUES 子句中指定 DEFAULT 关键字
示例4-6 通过显示方法设定默认值
INSERT INTO shohinIns(shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi)VALUES('0001','T恤衫','衣服',DEFAULT,790,'2009-09-20');
--确认插入的数据行
SELECT * FROM shohinIns WHERE shohin_id = '0007';
通过隐示方法插入默认值
插入默认值时也可以不使用 DEFAULT 关键字。
示例4-7 通过隐示方法设定默认值
INSERT INTO shohinIns(shohin_id,shohin_mei,shohin_bunrui,shiire_tanka,torokubi)VALUES('0001','T恤衫','衣服',790,'2009-09-20');
示例4-8 未设定默认值的情况
--省略 shiire——tanka 列(无约束):会赋予[NULL]
INSERT INTO shohinIns(shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,torokubi)VALUES('0001','T恤衫','衣服',790,'2009-09-20');
--省略 shiire——tanka 列(设置 NOT NULL 约束):错误!
INSERT INTO shohinIns(shohin_id,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi)VALUES('0001','衣服',790,500,'2009-09-20');
法则4-2 省略 INSERT 语句中的列名,就会自动设定为该列的默认值(没有默认值会设定为 NULL )。
从其他表中复制数据
示例4-9 创建 shohinCopy 表的 CRETAE TABLE 语句
--用来插入数据的商品复制表
CRETAE TABLE shihinCopy
(shohin_id CHAR(4) NOT NULL,
 shohin_mei VARCHAR(100) NOT NULL,
 shohin_bunrui VARCHAR(32) NOT NULL,
 hanbai_tanka INTEGER DEFAULT 0,
 shiire_tanka INTEGER,
 torokubi DATE,
 PRIMARY KEY (shohin_id));
示例4-10 INSERT...SELECT语句
--将商品表中的数据复制到商品复制表中(复制)
INSERT INTO shohinCopy(shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi)SELECT shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi FROM shohin;
多种多样的 SELECT 语句
示例4-11 创建表 shohinBunrui 表的 CREATE TABLE 语句
--用来汇总商品种类的表
CRETAE TABLE shohinBunrui
(shohin_bunrui VARCHAR(32) NOT NULL,
 sum_hanbai_tanka INTEGER,
 sum_shiire_tanka INTEGER,
 PRIMARY KEY (shohin_bunrui));
示例4-12 插入其他表数据合计值的 INSERT...SELECT 语句
INSERT INTO shohinBunrui(shohin_bunrui,sum_hanbai_tanka,sum_shiire_tanka)SELECT shohin_bunrui,sum(hanbai_tanka),sum(shiire_tanka) FROM shohin GROUP BY shohin_bunrui;
法则4-3 INSERT 语句的 SELECT 语句中,可以使用 WHERE 子句或者 GROUP BY 子句等任何 SQL 语法。(但使用 ORDER BY 子句并不会产生任何效果)
4-2 数据的删除( DELETE 语句的使用方法)
如果想将整个表全部删除,可以使用 DROP TABLE 语句,如果只想删除表中全部数据,需要使用 DELETE 语句。
如果想删除部分数据行,只需在 WHERE 子句中书写对象数据的条件即可。通过 WHERE 子句指定删除对象的 DELETE 语句称为搜索型 DELETE 语句。
DROP TABEL 语句和 DELETE 语句
DROP TABLE 语句可以将表完全删除。
DELETE 语句会留下表(容器)而删除表中额全部数据。
DELETE 语句的基础语法
语法4-2 保留数据表,仅删除全部数据行的 DELETE 语句
DELETE FROM <表名>;
示例4-13 清空 shohin 表
DELETE FROM shohin;
法则4-4 DELETE 语句的删除对象并不是表或者列,而是记录(行)。
指定删除对象的 DELETE 语句(搜索型 DELETE )
语法4-3 删除部分数据行的搜索型 DELETE
DELETE FROM <表名>
WHERE <条件>;
示例4-14 删除销售单价(hanbai_tanka)大于等于4000元的数据
DELETE FROM shohin
WHERE hanbai_tanka >= 4000;
--确认删除结果
SELECT * FROM shohin;
法则4-5 可以通过 WHERE 子句指定对象条件来删除部分数据。
语法4-A 只能删除表中全部数据的 TRUNCATE 语句
TRUNCATE <表名>;
4-3 数据的更新( UPDATE 语句的使用方法)
使用 UODATE 语句可以更改(更新)表中的数据。
更新部分数据行时可以使用 WHERE 来指定更新对象的条件。通过 WHERE 子句指定更新对象的 UPDATE 语句称之为搜索型 UPDATE 语句。
UPDATE 语句可以将列的值更新为 NULL。
同时更新多列时,可以在 UPDATE 语句的 SET 子句中,使用逗号分隔更新对象的多个列。
UPDATE 语句的基础语法
语法4-4 改变表中数据的 UPDATE 语句
UPDATE <表名>
SET <列名> = <表达式>;
示例4-15 将登记日期全部更新为”2009-10-10“
UPDATE shohin
SET torokubi = '2009-10-10';
--确认更新内容
SELECT * FROM shohin ORDER BY shohin_id;
指定条件的 UPDATE 语句(搜索型 UPDATE )
语法4-5 更新部分数据行的搜索型 UPDATE
UPDATE <表名>
SET <列名> = <表达式>
WHERE <条件>;
示例4-16 将商品种类为厨房用具的记录的销售单价更新为原来10倍
UPDATE shohin
SET hanbai_tanka = hanbai_tanka * 10
WHERE shohin_bunrui = '厨房用具';
--确认更新内容
SELECT * FROM shohin ORDER BY shohin_id;
使用NULL进行更新
示例4-17 将商品编号为0008的数据(圆珠笔)的登记日期更新为 NULL
UPDATE SHOHIN
SET torokubi = '0008';
--确认更新内容
SELECT * FROM shohin ORDER BY shohin_id;
法则4-6 使用 UPDATE 语句可以将值清空为 NULL (但只限于未设置 NOT NULL 约束的列)。
多列的更新
示例4-18 能够正确执行的繁琐的 UPDATE 语句
--一条 UPDATE 语句只更新一列
UPDATE shohin
SET hanbai_tanka = hanbai_tanka * 10
WHERE shohin_bunrui = '厨房用具';
UPDATE shohin
SET shiire_tanka = shiire_tanka / 2
WHERE shohin_bunrui = '厨房用具';
示例4-19 将示例4-18 处理合并为一条 UPDATE 语句
--使用逗号将列分隔排列
UPDATE shohin
SET hanbai_tanka = hanbai_tanka * 10,shiire_tanka = shiire_tanka / 2
WHERE shohin_bunrui = '厨房用具';
示例4-20 将示例4-18 处理合并为一条 UPDATE 语句
--将列用()括起来的列表形式
UPDATE shohin
SET (hanbai_tanka,shiire_tanka) = (hanbai_tanka * 10, shiire_tanka / 2)
WHERE shohin_bunrui = '厨房用具';
--确认更新内容
SELECT * FROM shohin ORDER BY shohin_id;
4-4 事务
事务是需要在同一处理单元中执行的一系列更新处理的集合。通过使用事务,可以对数据库中的数据更新处理和取消进行管理。
事务处理的终止指令包括 COMMIT (提交处理)和 ROLLBACK (取消处理)两种。
DBMS 的事务具有原子性(Atomicity)、一致性(Consistency)、隔离性(lsolation)和持久性(Durability)四种特性。统称为 ACID 特性。
什么是事务
事务就是需要在同一处理单元中执行的一系列更新处理的集合。
法则4-7 事务是需要在同一处理单元中执行的一系列更新处理的集合。
创建事务
语法4-6 事务的语法
事务开始语句;
DML 语句1;
DML 语句2;
DML 语句3;
……
事务结束语句(COMMIT 或者 ROLLBACK);
特定 SQL:
SQL Server、PostgreSQL
BEGIN TRANSACTION
MySQL
START TRANSACTION
Oracle、DB2

示例4-21 更新商品信息的事务
SQL Server、PostgreSQL
BEGIN TRANSACTION;
--将运动T恤的销售单价降低1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka - 1000
WHERE shohin_mei = '运动T恤';
--将T恤的销售单价上浮1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka + 1000
WHERE shohin_mei = 'T恤衫';
COMMIT;
MySQL
START TRANSACTION;
--将运动T恤的销售单价降低1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka - 1000
WHERE shohin_mei = '运动T恤';
--将T恤的销售单价上浮1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka + 1000
WHERE shohin_mei = 'T恤衫';
COMMIT;
Oracle、DB2
--将运动T恤的销售单价降低1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka - 1000
WHERE shohin_mei = '运动T恤';
--将T恤的销售单价上浮1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka + 1000
WHERE shohin_mei = 'T恤衫';
COMMIT;
COMMIT 是提交事务包含的全部更新处理的结束指令。
法则4-8 虽然我们可以不清楚事务开始的时点,但是在事务结束时一定要仔细进行确认。
ROLLBACK 是取消事务包含的全部更新处理的结束指令。
示例4-22 事务回滚的例子
SQL Server、PostgreSQL
BEGIN TRANSACTION;
--将运动T恤的销售单价降低1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka - 1000
WHERE shohin_mei = '运动T恤';
--将T恤的销售单价上浮1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka + 1000
WHERE shohin_mei = 'T恤衫';
ROLLBACK;
MySQL
START TRANSACTION;
--将运动T恤的销售单价降低1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka - 1000
WHERE shohin_mei = '运动T恤';
--将T恤的销售单价上浮1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka + 1000
WHERE shohin_mei = 'T恤衫';
ROLLBACK;
Oracle、DB2
--将运动T恤的销售单价降低1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka - 1000
WHERE shohin_mei = '运动T恤';
--将T恤的销售单价上浮1000元
UPDATE shohin
SET hanbai_tanka = hanbai_tanka + 1000
WHERE shohin_mei = 'T恤衫';
ROLLBACK;
事务处理何时开始
1.每条 SQL 语句就是一个事务(自动提交模式)
2.直到用户执行 COMMIT 或者 ROLLBACK 为止算作一个事务。
ACID 特性
DBMMS 的事务都遵循四种标准规格的约定。将这四种特性的首字母结合起来统称为 ACID 特性。
原子性(Atomicity):
原子性是指在事务结束时,其中所包含的更新处理要么全部执行,要么完全不执行。
一致性(Consistency):
一致性是指事务中包含的处理,要满足数据库提前设置的约束,如主键约束或者 NOT NULL 约束等。一致性也称为完整性。
隔离性(lsolation):
隔离性是指保证不同事务之间互不干扰的特性。
持久性(Durability):
持久性也称为耐久性,是指事务一旦结束,DBMS 会保证该时点的数据状态得以保存的特性。
第五章 复杂查询
5-1 视图
从SQL的角度来看,视图和表是相同的。两者的区别在于表中保存的是实际的数据,而视图中保持的是 SELECT 语句。
使用视图,可以轻松完成跨多表查询数据等复杂操作。
可以将常用的 SELECT 语句做成视图来使用。
创建视图需要使用 CREATE VIEW 语句。
视图包含”不能使用 ORDER BY “和”可对其进行有限制的更新“两项限制。
删除视图需要使用 DROP VIEW 语句。
视图和表
视图的优点:
第一点是由于视图无需保存数据,因此可以节省存储设备的容量。
示例5-1 通过视图等 SELECT 语句保存数据
SELECT shohin_bunrui,SUM(hanbai_tanka),SUM(shiire_tanka)
FROM shohin
GROUP BY shohin_bunrui
法则5-1 表中存储的是实际数据,而视图中保存的是从表中取出数据所使用的 SELECT 语句。
第二点是可以将频繁使用的 SELECT 语句保存成视图,这样子就不用每次都重新书写。
法则5-2 应该将经常使用的 SELECT 语句做成视图。
创建的视图方法
语法5-1 创建视图的 CREATE VIEW 语句
CREATE VIEW 视图名称(<视图列名1>,<视图列名2>,……)
AS
<SELECT 语句>
示例5-2 shohinSum 视图
CREATE VIEW shohinSum(shohin_bunrui,cnt_shohin)
AS
SELECT shohin_bunrui,COUNT(*)
FROM shohin
GROUP BY shohin_bunrui;
示例5-3 使用视图
SELECT shohin_bunrui,cnt_shohin
FROM shohinSum;
使用视图的查询
首先执行定义视图的 SELECT 语句,再执行在 FROM 子句中使用视图的 SELECT 语句。
示例5-4 视图
CREATE VIEW shohinSumJim (shohin_bunrui,cut_shohin)
AS
SELECT shohin_bunrui,cnt_shohin
FROM shohinSum
WHERE shohin_bunrui = '办公用品';
--确认是否创建出了视图
SELECT shohin_bunrui,cnt_shohin
FROM shohinSumJim;
法则5-3 应该避免在视图的基础上创建视图。
法则5-4 定义视图时不要使用 ORDER BY 子句。
法则5-5 视图和表需要同时进行更新,因此通过聚合得到的视图无法进行更新。
--确认数据是否已经添加到视图中
SELECT * FROM shohinJim;
语法5-2 删除视图的 DROP VIEW 语句
DROP VIEW 视图名称(<视图列名1>,<视图列名2>,……);
示例5-7 删除视图
DROP VIEW ShohinSum;
5-2 子查询
子查询就是一次性视图,与视图不同,子查询在 SELECT 语句执行完毕之后就会消失。
由于子查询需要命名,因此需要根据处理内容来指定恰当的名称。
标量子查询就是只能返回一行一列的子查询。
子查询和视图
示例5-8 视图 ShohinSum 和确认用的 SELECT 语句
--根据商品种类统计商品数量的视图
CREATE TABLE ShohinSum(shohin_bunrui,cnt_shohin)
AS
SELECT shohin_bunrui,COUNT(*)
FROM shohin
GROUP BY shohin_bunrui;
--确认视图是否已经创建成功
SELECT shohin_bunrui,cnt_shhohin
FROM ShohinSum;
法则5-6 子查询作为内层查询会首先执行。
子查询和名称
标量子查询
标量就是单一的意思。
法则5-7 标量子查询就是返回单一值的子查询。
5-3 关联子查询
关联子查询会在细分的组内进行比较时使用。
关联子查询和 GROUP BY 子句一样,也可以对表中的数据进行切分。
关联子查询的结合条件如果未出现在子查询之中就会发生错误。
普通的子查询和关联子查询的区别
法则5-8 在细分的组内进行比较时,需要使用关联子查询。
关联子查询也是用来对集合进行切分的
结合条件一定要写在子查询中
第六章 函数、谓词、CASE 表达式
6-1 各种各样的函数
根据用途,函数可以大致分为算术函数、字符串函数、日期函数、转换函数和聚合函数
函数的种类:
算术函数:加、减、乘、除
ABS-绝对值
语法6-1 ABS 函数
ABS(数值)
MOD-求余
语法6-2 MOD 函数
MOD(被除数,除数)
SQL Server使用%来计算余数。
ROUND-四舍五入
语法6-3 ROUND 函数
ROUND(对象数值,保留小数的位数)
字符串函数:
||-拼接
语法6-4 ||函数
字符串1||字符串2
||函数在 SQL Server 和 MySQL 中无法使用。
SQL Server 是使用+来连接字符串
MySQL 使用 CONCAT 来完成字符串拼接
LENGTH-字符串长度
语法6-5 LENGTH 函数
LENGTH(字符串)
LENGTH 函数在SQL Server 无法使用。
SQL Server 使用 LEN 函数计算字符串的长度。
LOWER-小写转换
语法6-6 LOWER 函数
LOWER(字符串)
REPLACE-字符串替换
语法6-7 REPLACE 函数
REPLACE(对象字符串,替换前的字符串,替换后的字符串)
SUBSTRING-字符串的截取
语法6-8a SUBSTRING 函数(PostgreSQL、MySQL)
SUBSTRING(对象字符串 FROM 截取的起始位置 FOR 截取的字符数)
语法6-8b SUBSTRING 函数(SQL Server)
SUBSTRING(对象字符串,截取的起始位置,截取的字符数)
语法6-C SUBSTR 函数(Oracle、DB2)
SUBSTR(对象字符串,截取的起始位置,截取的字符数)
UPPER-大写转换
语法6-9 UPPER 函数
UPPER(字符串)
日期函数:
CURRENT_DATE-当前日期
语法6-10a CURRENT_DATE 函数(PostgreSQL、MySQL)
CURRENT_DATE
CURRENT_DATE 函数在 SQL Server 无法执行
语法6-10b CURRENT_TIMESTAMP 函数(SQL Server)
SELECT CAST(CURRENT_TIMESTAMP AS DATE) AS CUR_DATE;
语法6-10C CURRENT_DATE 函数(Oracle)
SELECT CURRENT_DATE FROM dual;
语法6-10C CURRENT_DATE 函数(DB2)
SELECT CURRENT DATE FROM SYSIBM.SYSDUMMY1;
CURRENT_TIME-当前时间
语法6-11a CURRENT_TIME 函数(PostgreSQL、MySQL)
CURRENT_TIME
CURRENT_TIME 函数在 SQL Server 无法执行
语法6-11b CURRENT_TIMESTAMP 函数(Oracle)
SELECT CURRENT_TIMESTAMP FROM dual;
语法6-11C CURRENT_TIMESTAMP 函数(DB2)
SELECT CURRENT TIME FROM SYSIBM.SYSDUMMY1;
CURRENT_TIMESTAMP-当前日期和时间
语法6-12a CURRENT_TIMESTAMP 函数(SQL Server、PostgreSQL、MySQL)
SELECT CURRENT_TIMESTAMP;
语法6-12b CURRENT_TIMESTAMP 函数(Oracle)
SELECT CURRENT_TIMESTAMP FROM dual;
语法6-11C CURRENT TIMESTAMP 函数(DB2)
SELECT CURRENT TIMESTAMP FROM SYSIBM.SYSDUMMY1;
EXTRACT-截取日期元素
语法6-13a EXTRACT-函数(PostgreSQL、MySQL)
EXTRACT(日期元素 FROM 日期)
SQL Server无法使用 EXTRACT 函数
语法6-13b DATEPART 函数(SQL Server)
DATEPART(日期元素,日期)
语法6-13C EXTRACT-函数(Oracle)
SELECT EXTRACT(日期元素 FROM 日期) FROM DUAL;
语法6-13C EXTRACT-函数(DB2)
SELECT EXTRACT(日期元素 FROM 日期) FROM SYSIBM.SYSDUMMY1;
转换函数
CAST-类型转换
语法6-14 CAST 函数
CAST(转换前的值 AS 想要转换的数据类型)
示例6-17 将字符串类型转换成数值类型
SQL Server、PostgreSQL
SELECT CAST('0001' AS INTEGER) AS int_col;
MySQL
SELECT CAST('0001' AS SIGNED INTEGER) AS int_col;
Oracle
SELECT CAST('0001' AS INTEGER) AS int_col FROM DUAL;
DB2
SELECT CAST('0001' AS INTEGER) AS int_col FROM SYSIBM.SYSDUMMY1;
COALESCE-将 NULL 转换为其他值
语法6-15 COALESCE 函数
COALESCE(数据1,数据2,数据3……)
6-2 谓词
谓词就是返回值为真值的函数。
掌握 LIKE 的三种使用方法
需要注意 BETWEENT 包含三个参数
想要取得 NULL 数据是必须使用 IS NULL
可以将子查询作为 IN 和 EXISTS 的参数
什么是谓词
比较运算符的正式名称就是谓词,是需要满足特定条件(真值)的函数。
LIKE 谓词-字符串的部分一致查询
示例6-22 使用 LIKE 进行前方一致查询
SELECT * FROM <表名> WHERE <列名> LIKE 'DDD%';
其中”%“代表可变长度任意字符串
示例6-23 使用 LIKE 进行中间一致查询
SELECT * FROM <表名> WHERE <列名> LIKE '%DDD%';
示例6-24 使用 LIKE 进行后方一致查询
SELECT * FROM <表名> WHERE <列名> LIKE '%DDD';
示例6-25 使用 LIKE 和_(下划线)进行后方一致查询
SELECT * FROM <表名> WHERE <列名> LIKE '%__';
其中”_“代表一位长度任意字符串
BETWEEN谓词-范围查询
SELECT * FROM <表名> WHERE <列名> BETWEEN 100 AND 1000; 
IS NULL、IS NOT NULL -判断是否为 NULL
SELECT * FROM <表名> WHERE <列名> IS NULL; 
IN 谓词--OR 的简便用法
SELECT * FROM <表名> WHERE <条件1> OR <条件2>; 
SELECT * FROM <表名> WHERE <列名> IN(<值1>,<值2>,……); 
SELECT * FROM <表名> WHERE <列名> NOT IN(<值1>,<值2>,……); 
使用子查询作为 IN 谓词的参数
SELECT * FROM <表名> WHERE <列名> IN(<子查询结果集>); 
SELECT * FROM <表名> WHERE <列名> NOT IN(<子查询结果集>); 
EXIST 谓词
SELECT * FROM <表名> WHERE EXISTS(<子查询结果集>);
法则6-1 通常指定关联子查询作为 EXIST 的参数
法则6-2 作为 EXIST 参数的子查询中经常会使用 SELECT *。 
6-3 CASE 表达式
什么是 CASE 表达式
是在区分情况时使用的。
CASE 表达式的语法
语法6-16 搜索 CASE 表达式
CASE WHEN <判断表达式> THEN <表达式>
     WHEN <判断表达式> THEN <表达式>
     WHEN <判断表达式> THEN <表达式>
     ...
     ELSE <表达式>
END
CASE 表达式的使用方法
法则6-3 虽然 CASE 表达式中的 ELSE 子句可以省略,但还是希望大家不要省略。
法则6-4 CASE 表达式中的 END 不能省略。
第七章 集合运算
7-1 表的加减法
集合运算就是对满足同一规则的记录进行的加减等四则运算。
使用 UNION(并集)、INTERSECT(交集)、EXCEPT(差集)等集合运算符进行集合运算
集合运算符可以去除重复行。
如果希望集合运算符保留重复行,就需要使用 ALL 选项。
什么是集合运算
在数据库领域,表示记录的集合;
表的加法-UNION
SELECT * FROM EMP
UNION 
SELECT * FROM EMP
法则7-1
集合运算符会除去重复的记录。
集合运算的注意事项
注意事项1:作为运算对象的记录的列数必须相同
注意事项2:作为运算对象的记录中列的类型必须一致
注意事项3:可以使用任何 SELECT 语句,但 ORDER BY 子句只能在最后使用一次
包含重复行的集合运算-ALL 选项
SELECT * FROM EMP
UNION ALL
SELECT * FROM EMP
法则7-2 在集合运算符中使用 ALL 选项,可以保留重复行
选取表中公共部分-INTERSECT
SELECT * FROM EMP
INTERSECT
SELECT * FROM EMP;
记录的减法-EXCEPT
Oracle
SELECT * FROM EMP
MINUS
SELECT * FROM EMP;
7-2 联结(以列为单位对表进行联结)
什么是联结
联结就是将其他表中列添加过来,进行添加列的集合运算。
内联结-INNER JOIN
法则7-3 进行联结时需要在 FROM 子句中使用多张表
法则7-4 进行内联结时必须使用 ON 子句,并且要书写在 FROM 和 WHERE 之间。
法则7-5 使用联结时 SELECT 子句中的列需要按照<表的别名><列名>的格式进行书写。
外联结-OUTER JOIN
法则7-6 外联结使用 LEFT、RIGHT 来指定主表。使用二者所得到的结果完全相同。
3张以上表的联结
交叉联结-CROSS JOIN
法则7-7 那些过时和特定的联结书写方式,虽然我们自己不会使用,但还是希望大家能够读懂。
特定的联结语句和过时的语法
第八章 SQL 高级处理
8-1 窗口函数
什么是窗口函数
可以进行排序,生成序列号等一般的聚合函数无法实现的高级操作
窗口函数的语法
语法8-1 窗口函数
<窗口函数>OVER([PARTITION BY <列清单>] ORDER BY <排序用列清单>)
语法的基本使用方法-使用RANK函数
<RANK()>OVER([PARTITION BY <列清单>] ORDER BY <排序用列清单>)
法则8-1 窗口函数兼具分组和排序两种功能。
法则8-2 通过 PARTITION BY 分组后的记录集合称为”窗口“
无需指定 PARTITION BY
专用窗口函数的种类
法则8-3 由于专用窗口函数无需参数,所以通常括号中都是空的。
窗口函数的适用范围
法则8-4 原则上窗口函数只能在 SELECT 子句中使用
作为窗口函数使用的聚合函数
计算移动平均值
<开窗函数>OVER([PARTITION BY <列清单>] ORDER BY <排序用列清单> ROWS(行) <行数值> PRECEDING(之前))
<开窗函数>OVER([PARTITION BY <列清单>] ORDER BY <排序用列清单> ROWS(行) <行数值> FOLLOWING(之后))
<开窗函数>OVER([PARTITION BY <列清单>] ORDER BY <排序用列清单> ROWS(行) BETWEEN <行数值> PRECEDING(之前) AND <行数值> FOLLOWING(之后))
两个 ORDER BY
法则8-5 将聚合函数作为窗口函数使用时,会以当前记录为基准来决定统计对象的记录
8-2 GROUPING运算符
如果想要一次得到两个计算值可以使用 GROUPING 运算符
同时计算出合计值
ROKKUP-同时计算出合计值和小计值
SELECT <列名> FROM <表名> GROUP BY ROLLUP(列名);
法则8-6 超级分组记录默认使用 NULL 作为聚合键
法则8-7 ROLLUP 可以同时计算出合计和小计,是非常方便的工具
GROUPING 函数-让 NULL 更加容易分辨
SELECT GROUPING<列名> FROM <表名> GROUP BY ROLLUP(列名);
法则8-8 使用 GROUPING 函数能够简单地分辨出原始数据中的 NULL 和超级分组记录中的 NULL
CUBE-用数据来搭积木
SELECT CASE WHEN <条件表达式> THEN <值> ELSE <值> END,
FROM <表名>
GROUP BY CUBE(列名)
法则8-9 可以把 CUBE 理解为将使用聚合键进行切割的模块堆积成一个立方体。
GROUPING SETS -取得期望的积木
SELECT CASE WHEN <条件表达式> THEN <值> ELSE <值> END,
FROM <表名>
GROUP BY GROUPING SETS(列名)

SQL基础教程【日】MICK著 孙淼 罗勇译 ISBN 978-7-115-32269-2相关推荐

  1. 《SQL基础教程(第2版)》作者MICK:上帝存在于细节之中(图灵访谈)

    本文仅用于学习和交流目的,不得用于商业目的.非商业转载请注明作译者.出处,并保留本文的原始链接:http://www.ituring.com.cn/art... 访谈嘉宾:MICK, 就职于日本的一家 ...

  2. SQL基础教程MICK版 第一章总结

    SQL基础教程MICK版 ···第一章总结 数据库的结构 二维表 SQL操作大概的内容 要注意的规则 表的创建 表的删除与表定义的更新 表的数据键入 数据库的结构 最常见的系统结构就是 客户端\服务器 ...

  3. SQL基础教程MICK版 ···第五章总结

    SQL基础教程MICK版 ···第五章总结 视图 子查询 标量子查询 标量子查询.没有用标量子查询.常量的比较总结 关联子查询 自己的困惑 视图 1.视图的概念 ​ 1)从SQL的角度来看视图就是一张 ...

  4. SQL基础教程MICK版 --第四章总结

    SQL基础教程MICK版 ···第四章总结 DML操作.事务的概念.性质.和表现形式 DML操作之INSERT DML操作之UPDATE DML操作之DELETE.TRUNCATE 事务的概念,DBM ...

  5. SQL基础教程MICK版 ···第三章总结

    SQL基础教程MICK版 ···第三章总结 SELECT语句 关于上表的语句顺序 和 执行顺序 完整的语法结构 GROUP BY需要注意的点 用于限定GROUP BY的 HAVING子句 关于ORDE ...

  6. SQL基础教程MICK版 ···第六章总结

    SQL基础教程MICK版 ···第六章总结 函数 谓语 CASE语句 -- 有点像SWITCH语句 函数 函数的分类 算术函数 聚合函数 字符串函数 转换函数 日期函数 算术函数 ABS括号内数值 返 ...

  7. SQL基础教程MICK版 ···第二章总结

    SQL基础教程MICK版 ···第二章总结 前期准备 SELECT 语句基础 算术运算符.比较运算符和 NOT运算符 特殊的NULL 逻辑运算符 前期准备 应用第一章学的 建一个数据库 在该库中 建立 ...

  8. SQL基础教程MICK版 ···第七、八、九章总结

    SQL基础教程MICK版 ···第七.八.九章总结 表的联结 -- 内联结.外联结 表的合并--- UNION (其他操作对MYSQL不适用.没有看) 关于ROLLUP---显示小计和总计 驱动的概念 ...

  9. mysql集合运算_SQL基础教程(mick)学习

    数据处理通常情况下使用EXCEL,但也有其劣势,当数据量过大(10万条以上)就无法进行处理,现今数据量动辄几十上百万量的数据,就需要使用更高级的数据处理工具--DBMS. 学习的教材选择的是日本作家M ...

  10. [SQL基础教程] 1-5 表的删除和更新

    [SQL基础教程] 1-5 表的删除和更新 表的删除 语法 DROP TABLE <表名>; 法则 1-12 删除的表无法恢复 表定义的更新 语法 ALTER TABLE<表名> ...

最新文章

  1. Windows8 Metro开发 (03) : AppBar控件之BottomAppBar
  2. 【辟谣】java中的final方法在新版的jvm中能提高效率?
  3. 单机和分布式场景下,有哪些流控方案?
  4. 2013年第四届蓝桥杯C/C++ A组国赛 —— 第二题:骰子迷题
  5. redis——sentinel
  6. springboot项目中mybatis实现数据的基本查询
  7. 计算机网络—计算机网络核心
  8. 福建农林大学外事处界面设计
  9. VS2019MSDN的下载安装和使用
  10. 【财富空间】郝景芳:如何不被未来折叠
  11. OpenCV 调整图像亮度与对比度
  12. 『软件工程5』详解软件项目管理之软件的度量
  13. 信号与系统(3.1)- RLC 串联电路的零输入响应
  14. html5 判断页面加载,js判断页面是否加载完成的方法
  15. als算法参数_协调过滤算法之ALS
  16. 服务器有无线网卡么,全面认识服务器网卡:理论篇
  17. 文本相似度计算——Simhash算法(python实现)
  18. python 手机自动化_Win10 下python_appium的Android手机自动化环境搭建
  19. CRF和CQP的区别
  20. 【高效办公】OS模块对文件夹所有文件重命名

热门文章

  1. 安卓开机自启动app
  2. 基于Tushare量化分析示例
  3. 洪荒修真服务器名字可以修改吗,洪荒修真变态版
  4. php 正则格式化图片,php利用正则表达式格式化电话号码的方法
  5. 帝国插件自动采集文章主动推送给搜索引擎自动安装目录
  6. 面试-数据知识点准备
  7. 国外小伙用石头提炼硅,制作芯片,号称99秒“解决”芯片危机
  8. php师汤姆猫壁,汤姆猫家族与vivo游戏中心线上线下破壁联动
  9. 原生 js 实现点击按钮复制文本
  10. Java程序打包成jar文件