《SQL基础教程》 读书笔记
一些常见概念的对比和区分
1.DISTINCT使用
-- 取出数据表中的非重复数据
SELECT DISTINCT shohin_id FROM Shohin;
-- 计算去除重复数据后的数据行数
SELECT COUNT(DISTINCT shohin_bunrui) FROM Shohin;
2.指定升序或降序
SELECT shohin_id, shohin_mei, shohin_tanka FROM Shohin ORDER BY hanbai_tanka DESC;
3.别名
- GROUP BY不可以使用别名
- ORDER BY可以使用别名
4.聚合函数
只有SELECT和HAVING子句,以及ORDER BY子句中能够使用聚合函数
5.GROUP BY 和 ORDER BY
- 使用GROUP BY子句时,SELECT子句中不能出现聚合键之外的列。
- 使用ORDER BY子句时,SELECT子句之外的列也可以使用。
6.插入默认值
CREATE TABLE ShohinIns ( shohin_id CHAR(4) NOT NULL, hanbai_tanka INTEGER DEFAULT 0, -- 销售单价的默认值设定为0; PRIMARY KEY (shohin_id) );
-- 通过显示方法插入默认值(在VALUES子句中指定DEFAULT关键字)
INSERT INTO ShohinIns (shohin_id, hanbai_tanka) VALUES('0007',DEFAULT);
-- 通过隐式方法插入默认值(不使用DEFAULT关键字,只要在列清单和VALUES中省略设定了默认值的列就可以了)
INSERT INTO ShohinIns (shohin_id) VALUES('007');
注:更推荐第一种方法,更加一目了然地知道hanbai_tanka列使用了默认值,SQL语句地含义也更加任意理解。
省略INSERT语句中的列名,就会自动设定为该列的默认值(没有默认值会设定为NULL)。
7.从其他表中复制数据
插入数据的方法,除了使用VALUES子句指定具体的数据之外,还可以从其他表中复制数据。
执行INSERT…SELECT语句时,可以在表之间进行数据传递,可以用于数据备份时候使用。
INSERT INTO ShohinCopy (shohin_id, shohin_mei, shohin_bunrui) SELECT shohin_id, shobin_mei, shobin_bunrui FROM Shobin;
8.视图VIEW
视图包含“不能使用ORDER BY”和“可对其进行有限制的更新”两项限制。
删除视图需要使用DROP VIEW (<视图列名1>,<视图列名2>,...)
语句。
视图的使用:
CREATE VIEW ShohinSum(shohin_bunrui, cnt_shohin) --视图的列名 AS SELECT shohin_bunrui, COUNT(*) FROM Shohin GROUP BY shohin_bunrui;
-- 视图的使用
SELECT shohin_bunrui, cnt_shohin FROM ShohinSum;
shohin_bunrui cnt_shohin
衣服 2
办公用品 2
厨房用具 4
视图的限制1-定义视图时不能使用ORDER BY子句
视图的限制2-对视图进行更新
如果定义视图的SELECT语句能够满足某些条件,那么这个视图就可以被更新。例如:
- SELECT子句中未使用DISTINCT
- FROM子句中只有一张表
- 未使用GROUP BY子句
- 未使用HAVING子句
9.子查询
子查询就是一次性的视图(SELECT语句)。与视图不同,子查询在SELECT语句执行完毕之后就会消失。
由于子查询需要命名,因此需要根据处理内容来指定恰当的名称。
标量子查询就是只能返回一行一列的子查询。(是子查询返回一行一列,最终的查询并不一定。)
-- 直接在FROM子句中使用定义视图的SELECT语句
SELECT shohin_bunrui, cnt_shohin FROM ( SELECT shohin_bunrui, COUNT(*) AS cnt_shohin FROM Shohin GROUP BY shohin_bunrui ) AS ShohinSum;
子查询就是将用来定义视图的SELECT语句直接用于FROM子句当中。虽然“AS ShohinSum”就是子查询的名称,但由于该名称是一次性的,因此不会像视图那样保存在介质(硬盘)之中,而是在SELECT语句执行之后就消失了。子查询(subquery)就是”次级(sub)”的”查询(query)”。
标量子查询:就是返回单一值得子查询
SELECT shohin_id, shohinmei, hanbai_tanka FROM Shohin WHERE hanbai_tanka > (SELECT AVG(hanbai_tanka) FROM Shohin);
SELECT AVG(hanbai_tanka) FROM Shohin;
-- 上面就是标量子查询,SELECT语句的查询结果是单一的值。
标量子查询的返回值可以用在=或者<>这样需要单一值的比较运算符之中。这也是标量子查询的优势所在。
标量子查询的书写位置并不仅仅局限于WHERE子句中,通常任何可以使用单一值得位置都可以使用。也就是说,能够使用常数或者列名的地方,无论是SELECT子句、GROUP BY子句、HAVING子句,还是ORDER BY子句,几乎所有的地方都可以使用。
-- SELECT子句中使用标量子查询
SELECT shohin_id, shohin_mei, hanbai_tanka, (SELECT AVG(hanbai_tanka) FROM Shohin) AS avg_tanka FROM Shohin;
-- HAVING 子句中使用标量子查询
SELECT shohin——bunrui, AVG(hanbai_tanka) FROM Shohin GROUP BY shohin_bunrui HAVING AVG(hanbai_tanka) > (SELECT AVG(hanbai_tanka) FROM Shohin);
在WHERE子句中使用标量子查询:
“查询出销售单价高于平均销售单价得商品。”
SELECT shohin_id,shohinmei,hanbai_tanka FROM Shohin WHERE hanbai_tanka > AVG(hanbai_tanka)
虽然这样得SELECT语句看上去能够满足我们的要求,但是由于在WHERE子句中不能使用聚合函数,因此这样的SELECT语句是错误的。
-- 计算平均销售单价的标量子查询
SELECT AVG(hanbai_tanka)
FROM Shohin;
-- 选取出销售单价(hanbai_tanka)高于全部商品的平均单价的商品
SELECTR shohin_id,shohin_mei,shohin_tanka
FROM Shohin
WHERE hanbai_tanka > (SELECT AVG(hanbai_tanka) FROM Shohin)
10.关联子查询
- 关联子查询会在细分的组内比较时使用
- 关联子查询和GROUP BY子句一样,也可以对表中的数据进行切分
- 关联子查询的结合条件如果未出现在子查询之中就会发生错误
按此前所学,使用子查询就能选取出销售单价高于全部商品平均销售单价的物品。但是,我们改变下条件,选取出各商品分类中高于该分类平均销售单价的商品。
我们并不是要以全部商品为基础,而是要以细分的组为基础。对组内商品的平均价格和各商品的销售单价进行比较。
-- 按照商品分类计算平均价格
SELECT AVG(hanbai_tank) FROM Shohin GROUP BY shohin_bunrui;
-- 通过关联子查询按照商品种类对平均销售单价进行比较
SELECT shohin_id, shohin_mei, hanbai_tanka FROM Shohin AS S1 WHERE hanbai_tanka > ( SELECT AVG(hanbai_tanka) FROM Shohin AS S2 WHERE S1.shohin_bunrui = S2.shohin_bunrui GROUP BY shohin_bunrui );
这样我们就能选取出办公用品、衣服和厨房用具三类商品中高于该类商品平均销售单价的商品了。这里起关键作用的就是在子查询中添加的WHERE子句的条件。该条件的意思就是,在同一商品种类中对各商品的销售单价和平均单价进行比较。
关联子查询也是用来对集合进行切分的:
关联子查询执行时,DBMS内部的执行结果如下图所示:
11.CASE表达式
-- 搜索CASE表达式
CASE
WHEN <判断表达式> THEN <表达式>
WHEN <判断表达式> THEN <表达式>
WHEN <判断表达式> THEN <表达式>
...
ELSE <表达式>
END
-- 通过CASE表达式将A-C的字符串加入到商品分类当中
SELECT shohin_mei,
CASE WHEN shohin_bunrui = '衣服'
THEN 'A:' || shohin_bunrui
WHEN shohin_bunrui = '办公用品'
THEN 'B:' || shohin_bunrui
WHEN shohin_bunrui = '厨房用具'
THEN 'C:' || shohin_bunrui
ELSE NULL
END AS abc_shohin_bunrui
FROM Shohin;
shohin_mei abc_shohin_bunrui
T恤衫 A:衣服
打孔器 B:办公用品
运动T恤 A:衣服
菜刀 C:厨房用具
高压锅 C:厨房用具
叉子 C:厨房用具
擦菜板 C:厨房用具
圆珠笔 B:办公用品