[读书笔记]《SQL基础教程》

  《sql基础教程》这本书里面讲的内容大部分都是几个主流数据库(mysql、sql server、oracle)之间的共同点,知识点比较基础,适合sql入门学习。但对于已经系统学过数据的人来说,我个人认为可以不用再看了。因为系统学习过的内容包括了这本书里的,而且应该更为深入。
注:代码中"(" “)” 和 “[” "]"之间的语句表示可省略

一、数据库和sql
       1、DBMS种类
       2、SQL的种类
       3、创建表或数据库
       4、删除表
       5、表定义的更新
二、查询基础
       1、普通查询
       2、注释
       3、算术运算符
       4、比较运算符
       5、逻辑运算符
三、聚合与排序
       1、聚合函数
       2、分组查询
       3、指令执行顺序
       4、对查询结果进行排序
四、数据更新
       1、简单插入
       2、插入多行
       3、从其他表中复制数据
       4、删除表
       5、普通更新
       6、多行更新
       7、事务
五、复杂查询
       1、视图
       2、复杂查询
六、函数、谓词、CASE表达式
       1、常用函数
       2、谓词
       3、CASE表达式
七、集合运算
       1、表的加减法
       2、联结
八、SQL高级处理
       1、窗口函数
       2、GROUPING运算符


 

一、数据库和sql

1、DBMS的种类:
  1. 层次数据库 HDB
  2. 关系数据库 RDB
  3. 面向对象数据库 OODB
  4. XML数据库 XMLDB
  5. 键值存储数据库 KVS
2、SQL的种类:
  1. 数据定义语句(DDL ) create、drop、alter
  2. 数据操纵语句(DML) select、insert、update、delete
  3. 数据控制语句(DCL) commit、rollback、grant、revoke

SQL语句不区分大小写

  • 字符串常数、日期常数用单引号括起来
  • 别名用双引号
String sql1 = "SELECT user_name AS "用户名" ";
String sql2 = "INSERT INTO user VALUES('用户名')";

3、创建表或数据库
  1. 创建数据库:CREATE DATABASE < DB Name >;
  2. 创建表:CREATE TABLE < 表名 >(
    列名称1 数据类型,
    列名称2 数据类型,
    列名称3 数据类型,

    )
  3. 名称:
  • 半角英文字母(必须以此为开头)
  • 半角数字
  • 下划线(_)
  1. 删除表:DROP TABLE< 表名 >;
  2. 表定义的更新
  • 添加 ALTER TABLE < tableName > ADDcolumn < listName>
    (在Oracle和sql server中省略column)
    Oracle中添加多列:ALTER TABLE< tableName> ADD (< listName1>, < listName2>, < listName3> …)
  • 删除列: ALTER TABLE < tableName> DROP COLUMN < listName>;
    (在Oracle和sql server中省略COLUMN)


二、查询基础

1、普通查询:

SELECT (DISTINCT) p_name (AS) pn, p_type
WHEREp_type = '衣服’
FROM product AS p;

  • DISTINCT:删除重复列,只能用在第一个列名前
  • AS:为表/列定义别名,在oracle中省略
2、注释:
  • 单行注释: “–”之后
  • 多行注释 :“/” 和 “/”之间
3、算术运算符

      使用算数运算符(+、-、*、/)时,所有包含NULL的计算,结果都为NULL

  • 注意:NULL/0 不报错
          5 + NULL = NULL
4、比较运算符

     =、<>、>=、>、<=、< 的顺序不能颠倒

  • 注意:不能对NULL使用,可使用 IS NULL 或者 NOT NULL
5、逻辑运算符
SELECT p_name FROM product
WHERE NOT p_price >= 1000
	AND (register_date = '2019-09-11'
		OR register_date = '2019-09-20');
  • 优先级:AND > 0R
  • 三值逻辑:TRUE、FALSE、UNKNOW(值为NULL的时候)


三、聚合与排序

1、聚合函数
  1. 常用聚合函数:COUNT、SUM、AVG、MAX、MIN
  • 聚合函数不能写在WHERE子句中
  • COUNT(*):计算包含NULL在内的列
  • COUNT(<列名>):除了NULL以外的列数
  • AVG = (值的合计) / (值的个数)
  1. DISTINCT:删除重复列之后再进行计算
SELECT COUNT(DISTINCT p_type)
FROM product;

2、分组查询
SELECT p_type 
FROM product
GROUP BY p_type
HAVING AVG(s_price) >= 2500;

   使用GROUP BY之后,HAVINGSELECT 中只能包含:常数、聚合函数、聚合键

  • WHERE:指定行所对应的条件
  • HAVING:指定组所对应的条件
  • 单独使用GROUP BY分组是无序的
  • GROUP BY 后面紧跟着的 分组列名/聚合键 不能写别名
3、指令执行顺序:

     FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY

4、对查询结果进行排序
SELECT id, name, price 
FROM product
	ORDER BY price 
	 	DESC id;
  • 先排price,若相同再按id排序
  • ORDER BY:按照price的值排序,可使用聚合函数
  • DESC:降序,默认为升序:ASC


四、数据更新

1、简单插入
INSERT INTO product VALUES('1', "面包");
//VALUES后面的值要与数据库中的字段名一一对应,不可漏写
INSERT INTO product(name) VALUES("面包");
//VALUES后面的值只需与product后面的值一一对应即可

2、插入多行
  • INSERT INTO product VALUES(‘1’, ‘A’), (‘2’, ‘B’), (‘3’, DEFAULT);
        DEFAULT:插入默认值
  • 在Oracle中,INSERT INTO p VALUES(…)
                                       INTO p VALUES(…)
                      SELECT * FROM DUAL;
    最后的select语句并没有任何实际意义,但必须加在没有参照表的SQL语句后。
3、从其他表中复制数据
INSERT INTO p2(type, sum_price)
	SELECT type, SUM(price)
		FROM product
	GROUP BY type;

4、删除表
  1. 完全删除:DROP TABLE <表名>;

  2. 删除全部数据,保留表结构:

  • DELETE FROM <表名>
  • TRUNCATE <表名>; 速度较快,但是没有WHERE子句
5、普通更新
UPDATE < tableName >
	SET < listName > = < expression>;

6、多行更新
UPDATE < tableName >
	SET < listName > = < expression>[, < list2> = < expression2>, ...]
		WHERE < condition>;
UPDATE < tableName >
	SET (< listName >, < list2> , ...) = (< expression>, < expression2>, ...)
		WHERE < condition>;

7、事务
  1. 在SQLServer 和 PostagreSQL中:
BEGIN TRANSACTION
INSERT INTO chat VALUES('1');
COMMIT;
  1. 在MySQL中:
START TRANSACTION;
INSERT INTO chat VALUES('1');
COMMIT;
  1. 在Oracle 和 DB2 中:
INSERT INTO chat VALUES('1');
COMMIT;
  1. MySQL 和 SQL Server默认自动提交事务;
  2. Oracle需要自己手动提交事务。
  3. 事务的ACID特性:
  • 原子性 atomicity
  • 一致性 consistency
  • 隔离性 isolation
  • 持久性 durability


五、复杂查询

1、视图
  1. 创建视图
CREATE VIEW p(type, product)
AS
SELECT type, COUNT(*)
	FROM produc
		GROUP BY type;
  1. 删除视图
DROP VIEW <viewName>;

2、复杂查询
  1. 标量子查询:只能返回一行一列的结果
SELECT price
FROM product
WHERE price > 
	(SELECT AVG(price) 
	FROM p)
  • 注意:使用GROUP BY等可能不止一行一列
  1. 关联子查询
SELECT type, name, price
FROM p AS p1
WHERE price > 
	(SELECT AVG(price)
		FROM p AS p2
		WHERE p1.type = p2.type
		GROUP BY type);
  • 结合条件一定写在子查询中,因为子查询中的别名作用域只在子查询中,例如:p2的作用域只在括号内


六、函数、谓词、CASE表达式

1、常用函数
  1. ABS——绝对值
  2. MOD——求余
  • SQL Server使用%求余
  1. ROUND——四舍五入
  2. ||——拼接符
  • SQL中使用 ”+“
  • MySQL中使用CONCAT(a,b,c,……)
  1. LENGTH——求字符串长度
  2. LOWER/UPPER——大小写转换
  3. REPLACE——字符串替换
  • REPLACE(A, B, C):若A中包含B,则把该部分换成C
    (例如:REPLACE(‘123’, ‘2’, ‘6’):123 => 163
  1. CURRENT-TIMESTAMP——当前日期和时间
  2. CAST——类型转换
/* 把 '001' 转换成 整型*/
//SQL Server
SELECT CAST('001' AS INTEGER);

//MySQL
SELECT CAST('001' AS SIGNED INTEGER);

//Oracle
SELECT CAST('001' AS INTEGER) FROM DUAL;
  1. COALESCE——将NULL转换成其他值
//将NULL转换成1
SELECT COALESCE(NULL, 1);

//在Oracle中
SELECT COALESCE(NULL, 1) FROM DUAL;

2、谓词
  1. 谓词:返回值为真的函数(TRUE / FALSE /UNKNOW)
  2. LIKE——字符串的部分查询
SELECT * FROM product
WHERE p_name LIKE "%面包";
  1. BETWEEN——范围查询
SELECT column_name(s)
FROM table_name
WHERE column_name
BETWEEN value1 AND value2
  1. IS NULL / IS NOT NULL——判断是否为空
  2. IN(OR的简便用法)
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...)
  • 子查询作为IN的参数
// 查询价格小于等于100的产品名称
SELECT p_name
FROM product
WHERE p_name IN (
	SELECT p_price
		FROM product
			WHERE p_price <= 100
);
  1. EXIT——与IN作用相反,查询不存在条件中的记录
//查询价格不在100以内的产品名称
SELECT p_name
FROM product
WHERE p_name EXIT (
	SELECT p_price
		FROM product
			WHERE p_price <= 100
);

3、CASE表达式

1.简单表达式

SELECT 
	NAME,
	AGE,
	(CASE AGE
		WHEN '18' THEN '成年'
		ELSE '未成年' END
	 ) AS 是否成年
FROM STUDENT

查询前:

NAME AGE
zhang 10
xu 18
wang 19

查询结果:

NAME AGE 是否成年
zhang 10 未成年
xu 18 成年
wang 19 未成年
  • 注意条件,只有18才是成年
  1. 搜索表达式
SELECT 
	NAME,
	AGE,
	(CASE 
		WHEN AGE>'18' THEN '成年'
		ELSE '未成年' END
	 ) AS 是否成年
FROM STUDENT
  1. 在ORDER BY、GROUP BY 中使用CASE表达式
SELECT (CASE WHEN AGE>18 THEN '已成年'
			ELSE '未成年' END
		) AS 是否成年,
		COUNT(ID) AS 人数	
FROM STUDENT
GROUP BY (CASE WHEN AGE>18 THEN '已成年'
			  ELSE '未成年' END
		) 
ORDER BY (CASE WHEN AGE>18 THEN '已成年'
			  ELSE '未成年' END
		) DESC
  1. 在update中使用CASE表达式
UPDATE STUDENT
SET AGE=(CASE NAME WHEN '毛喜' THEN '19'
			WHEN '李明' THEN '17'
			ELSE AGE END)


七、集合运算

p1:

id name
1 zhang
2 wang
3 xu
4 yan

p2:

id name
1 zhang
5 yuan
6 hong

p3:

id age
1 19
2 17
3 18
4 19
5 18
6 20
1、表的加减法
  1. UNION——表的加法,并集
SELECT id, name FROM p1
UNION [ALL]
SELECT id, name FROM p2
[ORDER BY id];
id name
1 zhang
2 wang
3 xu
4 yan
1 zhang
5 yuan
6 hong
  • ALL:保留重复行,默认为不选取重复行
  • 两个SELECT语句后的列数和类型必须相同
  • ORDER BY 只在最后使用一次即可
  1. INTRESECT——选取表中公共部分
SELECT id FROM p1
INTERSECT [ALL]
SELECT id FROM p2;
id name
1 zhang
  1. EXCEPT——记录的减法
SELECT id FROM p1
EXCEPT 
SELECT id FROM p2
id name
2 wang
3 xu
4 yan
  • 在Oracle中,要将EXCEPT改成MINUS
2、联结
  1. INNER JOIN——内联结(与JOIN相同)
SELECT name
FROM p1
INNER JOIN p3
ON p1.id = p3.id;
id name age
1 zhang 19
2 wang 17
3 xu 18
4 yan 19
  1. OUTER JOIN——外联结
  • LEFT OUTER JOIN
SELECT * FROM p1
LEFT OUTER JOIN p2
ON p1.id = p2.id

LEFT左侧的表为主表(p1),产生p1的完全集,而p2表中匹配的则有值,没有匹配的则以null值取代。

id name id name
1 zhang 1 zhang
2 wang null null
3 xu null null
4 yan null null
  • RIGHT OUTER JOIN
SELECT * FROM p1
RIGHT OUTER JOIN p2
ON p1.id = p2.id

RIGHT侧的表为主表(p2),产生p2的完全集,而p1表中匹配的则有值,没有匹配的则以null值取代。

id name id name
1 zhang 1 zhang
5 yuan null null
6 hong null null
  • FULL OUTER JOIN
SELECT * FROM p1
RIGHT OUTER JOIN p2
ON p1.id = p2.id

产生p1和p2的并集。对于没有匹配的记录,则会以null做为值。

id name id name
1 zhang 1 zhang
2 wang null null
3 xu null null
4 yan null null
null null 5 yuan
null null 6 hong
  1. CROSS JOIN——交叉联结(笛卡尔积)
SELECT * FROM p1
CROSS JOIN p2

把表p1和表p2的数据进行一个NM的组合,即笛卡尔积。如本例会产生43=12条记录(很少用)。

  1. 三张以上表的联结
SELECT sp.shop_id, sp.shop_name, sp.p_id, p.p_name
FROM shop_product AS sp
INNER JOIN product AS p
ON sp.p_id = p.p_id
	INNER JOIN inven_product AS ip
		ON sp.p_id = ip.p_id
WHERE ip.i_id = 'poo1';


八、SQL高级处理

1、窗口函数
<窗口函数> OVER ( [PARTITION BY <列清单>]
		ORDER BY <排序用列清单> )
  • 能作为窗口函数的聚合函数:SUM、AVG、COUNT、MAX、MIN
  • RANK、DENSE_RANK、ROW_NUMBER……
  • PARITION BY :设定排序的对象范围
  • ORDER BY :把 排序用列清单 按一定顺序标上1,2,3……但整体是乱序的
  1. RANK()函数
SELECT p_name, p_type, s_price
RANK() OVER ( PARITION BY p_type
	ORDER BY s_price ) AS ranking
FROM p 
ORDER BY ranking;
  • 注意:若排序后,存在三条相同的值并列第一,则RANK()、DENSE_RANK()、ROW_NUMBER()排序的结果都不一样
    RANK():三条相同的结果排名都为1,第四条为4
    DENSE_RANK():三条相同的结果排名都为1,但第四条为2
    ROW_NUMBER():三条相同的结果一次排序,但序号不同,分别为1,2,3,第四条为4
2、GROUPING 运算符
  • GROUPING (< listName>) ,如果listName的值为NULL则返回1,其他则为0
  1. ROLLUP——同时得出合计和小计
SELECT p_type, r_date, SUM(s_price) AS sum_price
FROM p
GROUP BY ROLLUP (p_type, r_date);
  • 在MySQL中的语句为
SELECT p_type, r_date, SUM(s_price) AS sum_price
FROM p
GROUP BY p_type, r_date 
WITH ROLLUP;
  1. CUBE——用数据来搭积木
  2. GROUPING SETS——取得期望的积木
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章