第一章:了解SQL

1.1数据库基础

数据库(database)保存有组织的数据的容器(通常是一个文件或一组文件)

人们通常用数据库这个术语来代表他们使用的数据库软件。这是不正确的,它是引起混淆的根源。确切地说,数据库软件应称为DBMS(数据库管理系统)。数据库是通过DBMS创建和操纵的容器。数据库可以是保存在硬设备上的文件,但也可以不是。在很大程度上说,数据库究竟是文件还是别的什么东西并不重要,因为你并不直接访问数据库;你使用的是DBMS,它替你访问数据库。

表(table)某种特定类型数据的结构化清单。
模式(schema)关于数据库和表的布局及特性的信息。也就是数据库及表的属性或者说是配置
列(column)表中的一个字段。所有表都是由一个或多个列组成的。
数据类型(datatype)所容许的数据的类型。每个表列都有相应的数据类型,它限制(或容许)该列中存储的数据。
行(row)表中的一个记录。
主键(primarykey)一列(或一组列),其值能够唯一区分表中每个行。

聚集函数(aggregate function) 运行在行组上,计算和返回单个值的函数。

1.2什么是SQL

SQL是结构化查询语言(StructuredQueryLanguage)的缩写。SQL是一种专门用来与数据库通信的语言
优点:

  • SQL不是某个特定数据库供应商专有的语言。几乎所有重要的DBMS都支持SQL,所以,学习此语言使你几乎能与所有数据库打交道
  • SQL简单易学。它的语句全都是由描述性很强的英语单词组成,而且这些单词的数目不多。
  • SQL尽管看上去很简单,但它实际上是一种强有力的语言,灵活使用其语言元素,可以进行非常复杂和高级的数据库操作。

    DBMS专用的SQLSQL不是一种专利语言,而且存在一个标准委员会,他们试图定义可供所有DBMS使用的SQL语法,但事实上任意两个DBMS实现的SQL都不完全相同。本书讲授的SQL是专门针对MySQL的,虽然书中所讲授的多数语法也适用于其他DBMS,但不要认为这些SQL语法是完全可移植的。

第三章:使用MySQL

  1. # 创建数据库
  2. CREATE DATABASE 数据库名称;
  3. # 选择数据库
  4. USE 数据库名称;
  5. # 显示数据库链表 后面有个s
  6. SHOW DATABASES;
  7. # 显示当前数据库中的表 后面有个s
  8. SHOW TABLES;
  9. # 显示一个表的字段
  10. SHOW COLUMNS FROM 表名;
  11. # MySQL支持用DESCRIBE作为SHOW COLUMNS FROM的一种快捷方式。🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
  12. # 显示一个表的字段
  13. DESCRIBE 表名; 等同于 SHOW COLUMNS FROM 表名;

第四章:检索数据SELECT

为了使用SELECT检索表数据,必须至少给出两条信息——想选择什么,以及从什么地方选择。

  1. # 去重
  2. SELECT DISTINCT 字段名 FROM 表名;

第五章:排序检索数据ORDERBY

  1. # 对三个字段排序,且字段二 降序!
  2. SELECT 字段1,字段2,字段3 FROM 表名 ORDER BY 字段1,字段2 DESC,字段3;
  3. # 配合 LIMIT 找最大值和最小值
  4. SELECT 字段 FROM 表名 ORDER BY 字段 LIMIT 1;
  5. SELECT 字段 FROM 表名 ORDER BY 字段 DESC LIMIT 1;

第六章:过滤数据WHERE

MySQL在执行匹配时默认不区分大小写
...WHEREprod_name='**f**uses';可以匹配到Fuses

  1. # 空值检查
  2. SELECT 字段 FROM 表名 WHERE 字段 IS NULL;
  3. SELECT 字段 FROM 表名 WHERE 字段 IS NOT NULL;

第十章:创建计算字段

10.1拼接字段Concat:

  1. select concat(vend_name,'(',vend_country,')')
  2. from vendors
  3. order by vend_name;
  4. +----------------------------------------+
  5. | concat(vend_name,'(',vend_country,')') |
  6. +----------------------------------------+
  7. | ACME(USA) |
  8. | Anvils R Us(USA) |
  9. | Furball Inc.(USA) |
  10. | Jet Set(England) |
  11. | Jouets Et Ours(France) |
  12. | LT Supplies(USA) |
  13. +----------------------------------------+

10.2去空格trim()

  1. select concat(rtrim(vend_name),'(',rtrim(vend_country),')')
  2. from vendors
  3. order by vend_name;
  4. # rtrim()去掉右边所有空格
  5. # ltrim()去掉左边所有空格
  6. # trim()去掉两边

10.3使用别名AS

  1. select concat(rtrim(vend_name),'(',rtrim(vend_country),')') as vend_title
  2. from vendors
  3. order by vend_name;

10.4执行算术计算

  1. # 操作符: + - * /
  2. select prod_id,quantity,item_price, quantity*item_price as expanded_price
  3. from orderitems
  4. where order_num=20005;
  5. select 6*3;v
  6. +-----+
  7. | 6*3 |
  8. +-----+
  9. | 18 |
  10. +-----+
  11. select trim(' abd ');
  12. +-----------------+
  13. | trim(' abd ') |
  14. +-----------------+
  15. | abd |
  16. +-----------------+
  17. select now();
  18. +---------------------+
  19. | now() |
  20. +---------------------+
  21. | 2021-05-06 23:18:25 |
  22. +---------------------+

第十一章:使用数据处理函数

11.1文本处理函数

  1. # 大写upper()
  2. select vend_name,upper(vend_name)
  3. as vend_name_upcase
  4. from vendors order by vend_name;
  5. +----------------+------------------+
  6. | vend_name | vend_name_upcase |
  7. +----------------+------------------+
  8. | ACME | ACME |
  9. | Anvils R Us | ANVILS R US |
  10. | Furball Inc. | FURBALL INC. |
  11. | Jet Set | JET SET |
  12. | Jouets Et Ours | JOUETS ET OURS |
  13. | LT Supplies | LT SUPPLIES |
  14. +----------------+------------------+
  15. Left() 返回串左边的字符
  16. Length() 返回串的长度
  17. Locate() 找出串的一个子串
  18. Lower() 将串转换为小写
  19. LTrim() 去掉串左边的空格
  20. Right() 返回串右边的字符
  21. RTrim() 去掉串右边的空格
  22. Soundex() 返回串的SOUNDEX
  23. SubString() 返回子串的字符
  24. Upper() 将串转换为大写

11.2日期和时间处理函数

  1. AddDate() 增加一个日期(天、周等)
  2. AddTime() 增加一个时间(时、分等)
  3. CurDate() 返回当前日期
  4. CurTime() 返回当前时间
  5. Date() 返回日期时间的日期部分 //👈👈👈
  6. DateDiff() 计算两个日期之差
  7. Date_Add() 高度灵活的日期运算函数
  8. Date_Format() 返回一个格式化的日期或时间串
  9. Day() 返回一个日期的天数部分
  10. DayOfWeek() 对于一个日期,返回对应的星期几
  11. Hour() 返回一个时间的小时部分
  12. Minute() 返回一个时间的分钟部分
  13. Month() 返回一个日期的月份部分
  14. Now() 返回当前日期和时间
  15. Second() 返回一个时间的秒部分
  16. Time() 返回一个日期时间的时间部分
  17. Year() 返回一个日期的年份部分

使用WHEREorder_date=’2005-09-01’可靠吗?order_date的数据类型为datetime。这种类型存储日期及时间值。样例表中的值全都具有时间值00:00:00,但实际中很可能并不总是这样。如果用当前日期和时间存储订单日期(因此你不仅知道订单日期,还知道下订单当天的时间),怎么办?比如,存储的order_date值为2005-09-0111:30:05,则WHEREorder_date=’2005-09-01’失败。即使给出具有该日期的一行,也不会把它检索出来,因为WHERE匹配失败。
解决办法是指示MySQL仅将给出的日期与列中的日期部分进行比较,而不是将给出的日期与整个列值进行比较。为此,必须使用Date()函数。Date(order_date)指示MySQL仅提取列的日期部分,更可靠的SELECT语句为:

  1. select cust_id,order_num
  2. from orders
  3. where date(order_date) = '2005-09-01';
  4. +---------+-----------+
  5. | cust_id | order_num |
  6. +---------+-----------+
  7. | 10001 | 20005 |
  8. +---------+-----------+
  9. #范围查询
  10. select cust_id,order_num
  11. from orders
  12. where date(order_date) between '2005-09-01' and '2005-09-30' ;

如果要的是日期,请使用Date()如果你想要的仅是日期,则使用Date()是一个良好的习惯,即使你知道相应的列只包含日期也是如此。这样,如果由于某种原因表中以后有日期和时间值,你的SQL代码也不用改变。当然,也存在一个Time()函数,在你只想要时间时应该使用它。Date()和Time()都是在MySQL4.1.1中第一次引入的。

11.3数值处理函数

  1. Abs() 返回一个数的绝对值
  2. Cos() 返回一个角度的余弦
  3. Exp() 返回一个数的指数值
  4. Mod() 返回除操作的余数
  5. Pi() 返回圆周率
  6. Rand() 返回一个随机数
  7. Sin() 返回一个角度的正弦
  8. Sqrt() 返回一个数的平方根
  9. Tan() 返回一个角度的正切

第十二章:汇总数据

聚集函数(aggregate function) 运行在行组上,计算和返回单个值的函数。

  1. AVG() 返回某列的平均值
  2. COUNT() 返回某列的行数
  3. MAX() 返回某列的最大值
  4. MIN() 返回某列的最小值
  5. SUM() 返回某列值之和

12.1、AVG()函数

  1. select avg(prod_price) as avg_price
  2. from products
  3. where vend_id = 1003;
  4. +-----------+
  5. | avg_price |
  6. +-----------+
  7. | 13.212857 |
  8. +-----------+
  9. # 🔥AVG()函数忽略列值未NULL的行🔥

12.2、COUNT()函数

  1. select count(*) as num_cust
  2. from customers;
  3. +----------+
  4. | num_cust |
  5. +----------+
  6. | 5 |
  7. +----------+
  8. select count(cust_email) as num_cust
  9. from customers;
  10. +----------+
  11. | num_cust |
  12. +----------+
  13. | 3 |
  14. +----------+
  15. # 🔥如果指定列名,则指定列的值为空的行被COUNT()函数忽略,但如果COUNT()函数中用的是星号(*),则不忽略🔥

12.3、MAX()函数

  1. select prod_name,max(prod_price) as max_price
  2. from products;
  3. +--------------+-----------+
  4. | prod_name | max_price |
  5. +--------------+-----------+
  6. | .5 ton anvil | 55.00 |
  7. +--------------+-----------+
  8. # 🔥MAX()函数忽略列值为NULL的行。🔥

对非数值数据使用MAX() :
虽然MAX()一般用来找出最大的数值或日期值,但MySQL允许将它用来返回任意列中的最大值,包括返回文本列中的最大值。在用于文本数据时,如果数据按相应的列排序,则MAX()返回最后一行。

12.4、MIN()函数

  1. select prod_name,min(prod_price) as max_price
  2. from products;
  3. +--------------+-----------+
  4. | prod_name | max_price |
  5. +--------------+-----------+
  6. | .5 ton anvil | 2.50 |
  7. +--------------+-----------+
  8. # 🔥MIN()函数忽略列值为NULL的行。🔥

对非数值数据使用MIN() :
MIN()函数与MAX()函数类似,MySQL允许将它用来返回任意列中的最小值,包括返回文本列中的最小值。在用于文本数据时,如果数据按相应的列排序,则MIN()返回最前面的行。

12.5、SUM()函数

  1. select sum(item_price*quantity) as total_price
  2. from orderitems
  3. where order_num = 20005;
  4. +-------------+
  5. | total_price |
  6. +-------------+
  7. | 149.87 |
  8. +-------------+
  9. # 🔥SUM()函数忽略列值为NULL的行。🔥

在多个列上进行计算:
如本例所示,利用标准的算术操作符,所有聚集函数都可用来执行多个列上的计算。

12.6、聚集不同值DISTINCT

  1. select avg(distinct prod_price) as avg_price from products where vend_id = 1003;
  2. +-----------+
  3. | avg_price |
  4. +-----------+
  5. | 15.998000 |
  6. +-----------+
  7. select avg(prod_price) as avg_price from products where vend_id = 1003;
  8. +-----------+
  9. | avg_price |
  10. +-----------+
  11. | 13.212857 |
  12. +-----------+
  13. select distinct(vend_id) as avg_price
  14. from products;
  15. +-----------+
  16. | avg_price |
  17. +-----------+
  18. | 1001 | | 1002 | | 1003 | | 1005 |
  19. +-----------+

如果指定列名,则DISTINCT只能用于COUNT()。DISTINCT不能用于COUNT(),因此不允许使用COUNT(DISTINCT),否则会产生错误。类似地,*DISTINCT必须使用列名,不能用于计算或表达式。

12.7、组合聚集函数

  1. select count(*) as num_items,
  2. min(prod_price) as min_price,
  3. max(prod_price) as max_price,
  4. avg(prod_price) as avg_price
  5. from products;
  6. +-----------+-----------+-----------+-----------+
  7. | num_items | min_price | max_price | avg_price |
  8. +-----------+-----------+-----------+-----------+
  9. | 14 | 2.50 | 55.00 | 16.133571 |
  10. +-----------+-----------+-----------+-----------+

小结

聚集函数用来汇总数据。MySQL支持一系列聚集函数,可以用多种方法使用它们以返回所需的结果。这些函数是高效设计的,它们返回结果一般比你在自己的客户机应用程序中计算要快得多。

第二十三章:使用存储过程

存储过程简单说主要有三个好处:简单、安全、高性能

创建存储过程

  1. DELIMITER // 👈表示命令行实用程序使用//作为新的语句分隔符,👇下面END后面结束,最后恢复原来的分号分隔符
  2. 👇👇👇-- 表示注释
  3. -- Name: ordertotal
  4. -- Parameters: onumber = order number
  5. -- taxable = 0 if not taxable,1 if taxable
  6. -- ototal = order total variable
  7. CREATE PROCEDURE ordertotal( 👈创建存储过程 括号内填入参数
  8. IN onumber INT, 👈 IN 表示入参 后面跟类型
  9. IN taxable BOOLEAN, 👈 IN 表示入参 后面跟类型
  10. OUT ototal DECIMAL(8,2) 👈 IN 表示返回值 后面跟类型
  11. )COMMENT 'Obtain order total , optionally adding tax' 👈 COMMENT 表示描述即存储过程注释
  12. BEGIN 👈存储过程体开始
  13. -- Declare variable for total
  14. DECLARE total DECIMAL(8,2); 👈 DECLARE 创建变量 后面跟变量名 数据类型
  15. -- Declare tax percentage
  16. DECLARE taxrate INT DEFAULT 6; 👈 DECLARE 创建变量 后面跟变量名 数据类型
  17. -- Get the order total
  18. SELECT SUM(item_price*quantity)
  19. FROM orderitems
  20. WHERE order_num = onumber
  21. INTO total; 👈 将结果输出(保存)到total
  22. -- Is this taxable?
  23. IF taxable THEN 👈 IF 判断 0false 1(非0数字)为true
  24. -- Yes, so add taxrate to the total
  25. SELECT total+(total/100*taxrate) INTO total;
  26. END IF;
  27. -- And finally, save to out variable
  28. SELECT total INTO ototal; 👈 total保存的数据保存到我们的参数ototal中,这样我们就可以取到结果
  29. END // 👈存储过程体结束
  30. DELIMITER; 👈下面END后面结束,最后恢复原来的分号分隔符

调用存储过程

  1. # 第一步
  2. CALL ordertotal(20005,0,@total); 👈 CALL 调用存储过程
  3. # CALL调用并不会返回数据需要我们查询
  4. # 第二步
  5. SELECT @total; 👈 查询调用后的结果