SQL基础教程【日】MICK著 孙淼 罗勇译 ISBN 978-7-115-32269-2
阅后简记
第一章 数据库和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相关推荐
- 《SQL基础教程(第2版)》作者MICK:上帝存在于细节之中(图灵访谈)
本文仅用于学习和交流目的,不得用于商业目的.非商业转载请注明作译者.出处,并保留本文的原始链接:http://www.ituring.com.cn/art... 访谈嘉宾:MICK, 就职于日本的一家 ...
- SQL基础教程MICK版 第一章总结
SQL基础教程MICK版 ···第一章总结 数据库的结构 二维表 SQL操作大概的内容 要注意的规则 表的创建 表的删除与表定义的更新 表的数据键入 数据库的结构 最常见的系统结构就是 客户端\服务器 ...
- SQL基础教程MICK版 ···第五章总结
SQL基础教程MICK版 ···第五章总结 视图 子查询 标量子查询 标量子查询.没有用标量子查询.常量的比较总结 关联子查询 自己的困惑 视图 1.视图的概念 1)从SQL的角度来看视图就是一张 ...
- SQL基础教程MICK版 --第四章总结
SQL基础教程MICK版 ···第四章总结 DML操作.事务的概念.性质.和表现形式 DML操作之INSERT DML操作之UPDATE DML操作之DELETE.TRUNCATE 事务的概念,DBM ...
- SQL基础教程MICK版 ···第三章总结
SQL基础教程MICK版 ···第三章总结 SELECT语句 关于上表的语句顺序 和 执行顺序 完整的语法结构 GROUP BY需要注意的点 用于限定GROUP BY的 HAVING子句 关于ORDE ...
- SQL基础教程MICK版 ···第六章总结
SQL基础教程MICK版 ···第六章总结 函数 谓语 CASE语句 -- 有点像SWITCH语句 函数 函数的分类 算术函数 聚合函数 字符串函数 转换函数 日期函数 算术函数 ABS括号内数值 返 ...
- SQL基础教程MICK版 ···第二章总结
SQL基础教程MICK版 ···第二章总结 前期准备 SELECT 语句基础 算术运算符.比较运算符和 NOT运算符 特殊的NULL 逻辑运算符 前期准备 应用第一章学的 建一个数据库 在该库中 建立 ...
- SQL基础教程MICK版 ···第七、八、九章总结
SQL基础教程MICK版 ···第七.八.九章总结 表的联结 -- 内联结.外联结 表的合并--- UNION (其他操作对MYSQL不适用.没有看) 关于ROLLUP---显示小计和总计 驱动的概念 ...
- mysql集合运算_SQL基础教程(mick)学习
数据处理通常情况下使用EXCEL,但也有其劣势,当数据量过大(10万条以上)就无法进行处理,现今数据量动辄几十上百万量的数据,就需要使用更高级的数据处理工具--DBMS. 学习的教材选择的是日本作家M ...
- [SQL基础教程] 1-5 表的删除和更新
[SQL基础教程] 1-5 表的删除和更新 表的删除 语法 DROP TABLE <表名>; 法则 1-12 删除的表无法恢复 表定义的更新 语法 ALTER TABLE<表名> ...
最新文章
- Windows8 Metro开发 (03) : AppBar控件之BottomAppBar
- 【辟谣】java中的final方法在新版的jvm中能提高效率?
- 单机和分布式场景下,有哪些流控方案?
- 2013年第四届蓝桥杯C/C++ A组国赛 —— 第二题:骰子迷题
- redis——sentinel
- springboot项目中mybatis实现数据的基本查询
- 计算机网络—计算机网络核心
- 福建农林大学外事处界面设计
- VS2019MSDN的下载安装和使用
- 【财富空间】郝景芳:如何不被未来折叠
- OpenCV 调整图像亮度与对比度
- 『软件工程5』详解软件项目管理之软件的度量
- 信号与系统(3.1)- RLC 串联电路的零输入响应
- html5 判断页面加载,js判断页面是否加载完成的方法
- als算法参数_协调过滤算法之ALS
- 服务器有无线网卡么,全面认识服务器网卡:理论篇
- 文本相似度计算——Simhash算法(python实现)
- python 手机自动化_Win10 下python_appium的Android手机自动化环境搭建
- CRF和CQP的区别
- 【高效办公】OS模块对文件夹所有文件重命名