MySQL必知必会(1-12章)

第一章:了解SQL

数据库基础:(概念)

  1. 数据库软件:
    • DBMS(数据库管理系统)
  2. 数据库:
    • 通过DBMS创建和操纵的容器;
    • 保存有组织的数据的容器-->通常是一个文件或者一组文件;
  3. 表:
    • 某种特定类型的结构化清单;
    • 相同的数据库中不能两次使用想用的表名;
    • 不同的数据库中可以使用相同的表名;
  4. 列和数据类型:
    • 表有列组成,列中存储着表中某部分的信息;
    • 表中的一个字段,所有的表都是由一个或多个列组成的;
    • 每个列都有对应的数据类型;
  5. 数据类型:
    • 所容许的数据的类型,每个表列都有对应的数据类型,它限制或容许该类中存储的数据;
    • 优点:
      • 防止在数值字段中录入字符值;
      • 帮助正确的排序数据,在优化磁盘使用方面有重要作用;
  6. 行:
    • 表中的一个记录;
    • 别称记录,从技术上讲:行才是正确的术语;
  7. 主键:
    • 一列或一组列,其值能够唯一区分表中的每一行;
    • 唯一标识表中每行的这个列(或这组列)称为主键;
    • 满足主键的条件:
      • 任意两行都不具备相同的主键值;
      • 每个行都必须具有一个主键值(主键值不允许NULL值);
    • 关于主键的好习惯:
      • 不更新主键列的值;
      • 不重用主键列的值;
      • 不在主键列中使用可能会更改的值;
  8. 外键:(略......后面补充)

第2、3章:简介 使用MySQL

数据库配置:

可看之前写的博客:

https://www.cnblogs.com/xbhog/p/13550579.html

使用MySQL:

  1. 选择数据库:

    #显示数据库
    show databases;
    #使用数据库
    use DatabaseName;
    
    mysql> show databases;
    +----------------------+
    | Database             |
    +----------------------+
    | information_schema   |
    | MySQL_Crash_Course   |
    | MySQL_Crash_Course_1 |
    | demo                 |
    | mysql                |
    | performance_schema   |
    | sys                  |
    +----------------------+
    7 rows in set (0.00 sec)
    
    mysql> use MySQL_Crash_Course;
    Database changed
    
    
  2. 了解数据库和表

    返回当前选择的数据库内可用表的列表(show tables;)

    #显示表名
    show tables;
    mysql> show tables;
    +-------------------------+
    | Tables_in_MySQL_Student |
    +-------------------------+
    | customers               |
    | orderitems              |
    | orders                  |
    | productnotes            |
    | products                |
    | vendors                 |
    +-------------------------+
    6 rows in set (0.00 sec)
    
    show columns from customers
    

    解析:

    • show columns要求给出一个表名
    • 对每个字段返回一行
    • DESCRIBE customers==show columns from customers(两者作用相同)

第4章:检索数据

检索数据:

  1. 检索单个列:

    select prod_name from products;
    

    注:

    • 如果没有明确的排序查询结果,则返回的数据的顺序是没有特殊意义的;

    • 返回数据的顺序可能是数据被添加到表中的顺序,也可能不是;

    • 只要返回的想用数目的行就是正常的。

  2. 检索多个列:

    select prod_id,prod_name,prod_price from products;
    

    注:

    • 指定了三个列名,之间用逗号,
  3. 检索所有列:

    select * from products;
    

    注:

    • 使用通配符(*)表示;
    • 除非确定需要表中的每个列,否则最好不要使用;
    • 检索不需要的列通常会降低检索和应用程序的性能。、
  4. 检索不同的行:

    关键字:DISTINCT--->必须放到列名的前面

    select DISTINCT vend_id from products;
    

    注:

    • 不能部分使用DISTINCT关键字;
    • 除非指定的两个列都不同,否则所有行都将被检索出来。
  5. 限制结果:

    关键字:LIMIT

    select prod_name from products LIMIT 5;
    

    注:

    • 指MySQL返回不多于5行
    select prod_name from products LIMIT 5,5;
    

    注:

    • 从第五行开始的5行;
    • 第一个数据下标为0;
    • 带一个值的limit总是从第一行开始,给出的数为返回的行数;
    • 带两个值的limit可以指定从行号为第一个值的位置开始;
    • 如果行数不够的时候,MySQL将只返回它能返回的那些行。
  6. 使用完全限定的表名:

    #同时使用表名和列名
    select products.prod_name from products;
    
    #假定products确实位于crashcourse数据库中
    select products.prod_name from crashcourse.products;
    

    第5章:排序检索数据

    排序数据:

    平常进行查询的话是没有特定的顺序,

    select prod_name from products;
    

    检索的数据并不是纯粹的随机顺序显示的,数据后来进行过更新或者删除,则此顺序将会收到MySQL重用回收存储空间的影响

    注:如果不明确规定排序顺序,则不应该假定检索出的数据顺序有意义。

    关键字:order by---取出一个或多个列的名字,据此对输出进行排序;

    select prod_name from products order by prod_name;
    

    prod_name以字母顺序排序数据

按多个列排序:

指定列名,列名之间用逗号分割;

select prod_id, prod_name,prod_price from products order by prod_price,prod_name;

首先按照价格排序,然后按照名字排序;

仅在多个行具有相同的prod_price值时才对产品按照prod_name进行排序,如果prod_price列中所有的值都是唯一的,则不会按prod_name排序。

指定排序方向:

MySQL默认的排序时ASC(升序);

关键字:desc (降序)

select prod_id,prod_name,prod_price from products order by prod_price desc;

筛选出最贵的依次放在前面

select prod_id,prod_name,prod_price from products order by prod_price desc,prod_name;

只对prod_price有效;

找到最高/最低的值:order by+limit;

select prod_price from products order by prod_price desc limit 1 ;

第6章:过滤数据

使用where:

关键字:where,where+搜索条件/过滤条件;

demo:

select prod_name,prod_price from products where prod_price =2.50;

同时使用where与order by时,应该order by在where之后,否则将会产生错误;

where的操作符:

运算符 描述
= 等于
<> 不等于。注释:在 SQL 的一些版本中,该操作符可被写成 !=
> 大于
< 小于
>= 大于等于
<= 小于等于
BETWEEN 在某个范围内
LIKE 搜索某种模式
IN 指定针对某个列的多个可能值

检查单个值:

demo:

select prod_name,prod_proce from products where prod_name ='fuses'

例:列出价格小于10美元的所有产品:

select prod_name,prod_price from products where prod_price<10;

列出价格小于等于10美元的所有产品:

select prod_name,prod_price from products where prod_price<=10;

不匹配检查:

列:不是由供应商1003制造的所有产品

select vend_id,prod_name from products where vend_id <>1003;
select vend_id,prod_name from products where vend_id !=1003;
select vend_id,prod_name from products where not vend_id =1003;

范围值检查:

关键字:between 开始值 and 结束值

例:检索价格在5美元和10美元之间的所有产品

selecy prod_name,prod_price from products where prod_price between 5 and 10;

between关键字匹配的范围中所有的值,包括指定的开始值与结束值;

空值检查:

在一个列中不包含值时,称为包含空值NULL;

NULL 无值,它与字段包含0,空字符串或者仅仅包含空格不同;

关键字:is null;检查具有NULL的列

select prod_name from products where prod_price is null;
select cust_id from customers where cust_email is null;

NULL与不匹配:

在通过过滤选择出不具有特定值的行时,你可能希望返回具有NULL值的行。但是,不行。因为未知具有特殊的含义,数据库不知道它们是否匹配,所以在匹配过滤或不匹配过滤时不返回它们;

因此,再过滤数据时,一定要验证返回数据中确实给出了被过滤列具有的NULL的行。

第7章:数据过滤

组合hwere子句:

关键字:and or not in (括号)-->计算优先级

操作符:用来联结或改变where子句中的子句的关键字,也成为逻辑操作符

AND操作符:

关键字:and 用来指示检索满足所有给定条件的行;

select prod_id,prod_name,prod_price from products where vend_id =1003 and prod_price <=10;

注:还可以添加多个过滤条件,每添加一个就要使用一个and;

or操作符:

关键字:or 检索任意给定的条件,而不是同时匹配两个或多个条件。

select prod_id,prod_name,prod_price from products where vend_id =1003 or vend_id =1002;

计算次序:

and在计算次序中优先级更高

列出价格为10美元以上并且由1002或者1003制造的所有产品:

select vend_id,prod_price,prod_name from products where vend_id =1002 or vend_id =1003 and prod_price >=10

输出:

+---------+------------+----------------+
| vend_id | prod_price | prod_name      |
+---------+------------+----------------+
|    1003 |      13.00 | Detonator      |
|    1003 |      10.00 | Bird seed      |
|    1002 |       3.42 | Fuses          |
|    1002 |       8.99 | Oil can        |
|    1003 |      50.00 | Safe           |
|    1003 |      10.00 | TNT (5 sticks) |
+---------+------------+----------------+

上面的输出并没有满足我们的条件;原因是;and的优先级高,所以执行的时候是(vend_id =1002)or(vend_id =1003 and prod_price >=10);而不是从左到右的方式执行;

整解:使用括号明确的分组

select vend_id,prod_price,prod_name from products where (vend_id =1002 or vend_id =1003) and prod_price >=10;
+---------+------------+----------------+
| vend_id | prod_price | prod_name      |
+---------+------------+----------------+
|    1003 |      13.00 | Detonator      |
|    1003 |      10.00 | Bird seed      |
|    1003 |      50.00 | Safe           |
|    1003 |      10.00 | TNT (5 sticks) |
+---------+------------+----------------

不要过分的依赖默认的计算次序,使用圆括号没有什么坏处,他能消除歧义。

IN操作符:

关键字:IN 用来指定条件范围,范围中的每个条件都可以进行匹配

IN取合法值的由逗号分割的清单,全部包括在圆括号中;

select prod_name,prod_price from products where vend_id in(1002,1003) order by prod_name;

+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| Bird seed      |      10.00 |
| Carrots        |       2.50 |
| Detonator      |      13.00 |
| Fuses          |       3.42 |
| Oil can        |       8.99 |
| Safe           |      50.00 |
| Sling          |       4.49 |
| TNT (1 stick)  |       2.50 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+
9 rows in set (0.00 sec)

IN操作符的作用与OR有相同的功能;

select prod_name,prod_price from products where vend_id=1002 or vend_id=1003 order by prod_name;
+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| Bird seed      |      10.00 |
| Carrots        |       2.50 |
| Detonator      |      13.00 |
| Fuses          |       3.42 |
| Oil can        |       8.99 |
| Safe           |      50.00 |
| Sling          |       4.49 |
| TNT (1 stick)  |       2.50 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+

IN操作符的好处:

  1. 在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。

  2. 在使用IN时,计算的次序更容易管理(因为使用的操作符更少)。

  3. IN操作符一般比OR操作符清单执行更快。

  4. IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句。第11章将对此进行详细介绍。

  5. IN WHERE子句中用来指定要匹配值的清单的关键字,功能与OR相当。

NOT操作符:

关键字:not 用来否定后跟条件的关键字

例:列出除1002和1003之外的所有供应商制造的产品

select prod_name,prod_price from products where vend_id not in (1002,1003) order by prod_name;
+--------------+------------+
| prod_name    | prod_price |
+--------------+------------+
| .5 ton anvil |       5.99 |
| 1 ton anvil  |       9.99 |
| 2 ton anvil  |      14.99 |
| JetPack 1000 |      35.00 |
| JetPack 2000 |      55.00 |
+--------------+------------+
5 rows in set (0.00 sec)

第8章:用通配符进行过滤

like操作符:

关键字:LIKE 从技术上讲,LIKE是谓词而不是操作符;

通配符:用来匹配值的一部分的特殊字符;

搜索模式:由字面值、通配符或者两者组合构成的搜索条件;

LIKE指示MySQL后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。

百分号(%)通配符:

%表示任何字符出现的次数;

例:找出所有以jet开头的产品

select prod_id,prod_name from products where prod_name like 'jet%';
+---------+--------------+
| prod_id | prod_name    |
+---------+--------------+
| JP1000  | JetPack 1000 |
| JP2000  | JetPack 2000 |
+---------+--------------+
2 rows in set (0.00 sec)

通配符可以在搜索模式中任意位置应用,并且可以使用多个通配符

select prod_id,prod_name from products where prod_name like '%anvil%';
+---------+--------------+
| prod_id | prod_name    |
+---------+--------------+
| ANV01   | .5 ton anvil |
| ANV02   | 1 ton anvil  |
| ANV03   | 2 ton anvil  |
+---------+--------------+
3 rows in set (0.00 sec)

通配符也可以出现在搜索模式的中间

mysql> select prod_id,prod_name from products where prod_name like 's%e';
+---------+-----------+
| prod_id | prod_name |
+---------+-----------+
| SAFE    | Safe      |
+---------+-----------+
1 row in set (0.00 sec)

%除了一个或者多个字符外,还可以匹配0个字符;%代表搜索模式中给定位置的0 个 1个或者多个字符;

注:尾空格可能会干扰通配符匹配(%anvil)

解决:在搜索模式后附加一个%,或者使用函数---11章介绍

注:但是通配符不能匹配NULL

下划线(_)通配符:

作用:只能匹配单个字符而不是多个字符;

(_)

mysql> select prod_id,prod_name from products where prod_name like '_ ton anvil';
+---------+-------------+
| prod_id | prod_name   |
+---------+-------------+
| ANV02   | 1 ton anvil |
| ANV03   | 2 ton anvil |
+---------+-------------+
2 rows in set (0.00 sec)

对照(%):

mysql> select prod_id,prod_name from products where prod_name like '% ton anvil';
+---------+--------------+
| prod_id | prod_name    |
+---------+--------------+
| ANV01   | .5 ton anvil |
| ANV02   | 1 ton anvil  |
| ANV03   | 2 ton anvil  |
+---------+--------------+
3 rows in set (0.00 sec)

使用通配符的技巧:

通配符很有用,但也是有代价的:通配符搜索的处理一般要比操作符搜索要花更长的时间。
通配符使用需要注意的几点:

  • 不要过度使用通配符,如果其他操作可以达到相同的目的,使用其他操作符
  • 在确实需要使用通配符时,除非绝对必要,否则不要把他们用在搜索模式的开始处。通配符置于开始处,搜索最慢
  • 仔细注意通配符的位置,如果放错地方,可能不会返回想要的数据。

第9章:用正则表达式进行搜索

什么是正则表达式:

  1. 用来匹配文本的特殊字符集合
  2. 关键字:regexp(REGEXP)

基本字符匹配:

例1:检索列prod_name包含文本1000的所有行

mysql> select prod_name from products where prod_name regexp '1000' order by prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
+--------------+
1 row in set (0.01 sec)

例2:

mysql> select prod_name from products where prod_name regexp '.000' order by prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.00 sec)

正则语法:"."匹配任意一个字符

比较:LIKE

mysql> select prod_name from products where prod_name like '1000' order by prod_name;
Empty set (0.00 sec)

mysql> select prod_name from products where prod_name like '%1000' order by prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
+--------------+
1 row in set (0.00 sec)

解释:

​ LIKE匹配的是整个列,如果被匹配的文本在列值中出现,LIKE将不会找到它,相应的行也不被返回(除非使用通配符 -% _);

​ 而REGEXP在列值内进行匹配,如果匹配的文本在列值中出现,REGEXP将会找到它,相应的行将被返回

匹配大小写的问题:

​ MySQL在本本3.23.4后不区分大小写,为区分大小写使用关键字:BINARTY

进行OR匹配:

为搜索两个串之一使用---'|'

例:

mysql> select prod_name from products where prod_name REGEXP '1000 | 2000' order by prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 2000 |
+--------------+
1 row in set (0.00 sec)

mysql> select prod_name from products where prod_name REGEXP '1000|2000' order by prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.00 sec)

注:注意书写正则的格式,严格按照规范,否则匹配的完全不同结果。

拓:

可以给出多个条件:

select prod_name from products where prod_name REGEXP '1000|2000|.ton' order by prod_name;
+--------------+
| prod_name    |
+--------------+
| .5 ton anvil |
| 1 ton anvil  |
| 2 ton anvil  |
| Detonator    |
| JetPack 1000 |
| JetPack 2000 |
+--------------+
6 rows in set (0.00 sec)

匹配几个字符之一:

匹配特定的的字符,可以指定一组用''[]"括起来的字符完成;

select  prod_name from products where prod_name REGEXP '[123] Ton' order by prod_name;
+-------------+
| prod_name   |
+-------------+
| 1 ton anvil |
| 2 ton anvil |
+-------------+
2 rows in set (0.00 sec)

[]是另一种形式的OR语句,最好使用[],虽然功能与|相同,但是|有时候有歧义,

select  prod_name from products where prod_name REGEXP '1|2|3 Ton' order by prod_name;
+---------------+
| prod_name     |
+---------------+
| 1 ton anvil   |
| 2 ton anvil   |
| JetPack 1000  |
| JetPack 2000  |
| TNT (1 stick) |
+---------------+
5 rows in set (0.00 sec)

正确的写法需要加():

select  prod_name from products where prod_name REGEXP '(1|2|3) Ton' order by prod_name;
+-------------+
| prod_name   |
+-------------+
| 1 ton anvil |
| 2 ton anvil |
+-------------+
2 rows in set (0.00 sec)

与匹配[123]相反的是匹配[123]之外的:[^123]

select  prod_name from products where prod_name REGEXP '[^123] Ton' order by prod_name;
+--------------+
| prod_name    |
+--------------+
| .5 ton anvil |
+--------------+
1 row in set (0.00 sec)

拓:[123]--->[1-3] (定义范围)

匹配特殊字符:

例:匹配包含 “ . ”字符的值

为匹配特殊字符,必须用\\作为前导;\\-表示查找-,\\.表示查找 .;---->转义

select vend_name from vendors where vend_name regexp '\\.' order by vend_name;
+--------------+
| vend_name    |
+--------------+
| Furball Inc. |
+--------------+
1 row in set (0.00 sec)

假设我们需要匹配常用特殊字符即可这么写:

\\[ 匹配左方括号
\\. 匹配点号
\\] 匹配右方括号
\\| 匹配竖线
\\\ 匹配反斜杠自己本身

依次类推,其他特殊的字符串也可以使用这么方式处理。

双反斜杠加上一些字母还可以表示特殊的含义。

比如:

\\f 换页
\\n 换行
\\r 回车
\\t 制表符
\\v 纵向制表符

在一般的编程语言中,转义一般使用一个反斜线,在Mysql中为什么是两个才行?原因是:Mysql自己需要一个来识别,然后Mysql会将扣除了一个反斜杠的剩余的部分完全的交给正则表达式库解释,所以加起来就是两个了。

匹配字符类:

我们直接给出表直接参阅。

说明
[:alnum:] 任意数字和字母。相当于[a-zA-Z0-9]
[:alpha:] 任意字符。相当于[a-zA-z]
[:blank:] 空格和制表。相当于[(双斜杠,segmentfault这里双斜杠打不出来)t]
[:cntrl:] ASCII控制字符(ASCII 0 到31和127)
[:digit:] 任意数字。相当于[0-9]
[:graph:] 与[:print:]相同,但是不包含空格
[:lower:] 任意的小写字母。相当于[a-z]
[:print:] 任意可打印字符
[:punct:] 既不在[:alnum:]又不在[:cntrl:]中的任意字符
[:space:] 包括空格在内的任意空白字符。
[:upper:] 任意大写字母。相当于[A-Z]
[:xdigit:] 任意十六进制的数字。相当于[a-fA-F0-9]

匹配多个实例:

正则表达式重复元字符:

元字符 作用
* 重复0次或者多次
+ 重复一次或者多次。相当于
? 重复0次或者1次
重复n次
重复至少n次
重复n-m次

例:

select prod_name from products where prod_name regexp '\\([0-9] sticks?\\)' order by prod_name;
+----------------+
| prod_name      |
+----------------+
| TNT (1 stick)  |
| TNT (5 sticks) |
+----------------+
2 rows in set (0.00 sec)

解释:

\\( 匹配 \\) 【0-9】-->匹配范围中的任意数字,sticks?匹配stick+sticks,(s后面的?使s可选)

例:

select prod_name from products where prod_name regexp '[[:digit:]]{4}' order by prod_name;
--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+

解释:

​ [[:digit:]]{4}匹配连在一起的任意4位数字。

定位符:

^ 文本开始
$ 文本结束
[[:<:]] 词的开始
[[:>:]] 词的结束

^ 的双重作用:(1)集合中,否定集合;(2)表示文本开始

例:找出一个数(包括以小数点开始的数)开始的所有产品;

select prod_name from products prod_name regexp '^[0-9\\.]' order by prod_name;
+--------------+
| prod_name    |
+--------------+
| .5 ton anvil |
| 1 ton anvil  |
| 2 ton anvil  |
+--------------+
3 rows in set (0.00 sec)

对照没有^:

select prod_name from products where prod_name regexp '[0-9\\.]' order by prod_name;
+----------------+
| prod_name      |
+----------------+
| .5 ton anvil   |
| 1 ton anvil    |
| 2 ton anvil    |
| JetPack 1000   |
| JetPack 2000   |
| TNT (1 stick)  |
| TNT (5 sticks) |
+----------------+
7 rows in set (0.00 sec)

解释:^匹配串的开始,因此[0-9\.]只在.或者任意数字为串中第一个字符时菜匹配他们。

^的双重用途:

在集合中[^]用来否定该集合,其他则用来指串的开始处。

第10章:创建计算字段

计算字段相关概念:

计算字段与列不同,计算字段并不实际存在与数据库表中,计算字段是运行时在select语句中创建的;

字段:基本与列的意思相同,经常互换使用,不过数据库列一般称为列。

拼接字段:

拼接(concatenate)将值联结到一起构成单个值;

函数:Concat()

注:多数DBMS使用+或者||拼接

mysql> select concat(vend_name,"(",vend_country,")") from vendors order by vend_name ;
+----------------------------------------+
| concat(vend_name,"(",vend_country,")") |
+----------------------------------------+
| ACME(USA)                              |
| Anvils R Us(USA)                       |
| Furball Inc.(USA)                      |
| Jet Set(England)                       |
| Jouets Et Ours(France)                 |
| LT Supplies(USA)                       |
+----------------------------------------+
6 rows in set (0.01 sec)

Concat()拼接串,需要一个或多个指定的串,各个串之间用逗号分割;

RTrim()函数:删除数据右侧多余的空格来整理数据;

select concat(rtrim(vend_name),"(",rtrim(vend_country),")") from vendors order by vend_name ;
+------------------------------------------------------+
| concat(rtrim(vend_name),"(",rtrim(vend_country),")") |
+------------------------------------------------------+
| ACME(USA)                                            |
| Anvils R Us(USA)                                     |
| Furball Inc.(USA)                                    |
| Jet Set(England)                                     |
| Jouets Et Ours(France)                               |
| LT Supplies(USA)                                     |
+------------------------------------------------------+
6 rows in set (0.02 sec)

LTrim()去掉串左边的空格,Trim()除去串左右两边的空格

使用别名:(alias)

关键字:AS

mysql> select concat(rtrim(vend_name),"(",rtrim(vend_country),")")  as vend_title from vendors order by vend_name ;
+------------------------+
| vend_title             |
+------------------------+
| ACME(USA)              |
| Anvils R Us(USA)       |
| Furball Inc.(USA)      |
| Jet Set(England)       |
| Jouets Et Ours(France) |
| LT Supplies(USA)       |
+------------------------+
6 rows in set (0.00 sec)

AS指示SQL创建一个包含指定计算的名为vend_title 的计算字段,与实际的表一样可以调用;

别名有时也称导出列,代表的内容相同。

执行算数计算:

首先检索订单号20005中的所有物品:

mysql> select * from orderitems where order_num =20005;
+-----------+------------+---------+----------+------------+
| order_num | order_item | prod_id | quantity | item_price |
+-----------+------------+---------+----------+------------+
|     20005 |          1 | ANV01   |       10 |       5.99 |
|     20005 |          2 | ANV02   |        3 |       9.99 |
|     20005 |          3 | TNT2    |        5 |      10.00 |
|     20005 |          4 | FB      |        1 |      10.00 |
+-----------+------------+---------+----------+------------+
4 rows in set (0.01 sec)

汇总物品的价格:单价乘以数量

mysql> select prod_id,quantity,item_price,quantity*item_price AS expanded_price from orderitems where order_num = 20005;
+---------+----------+------------+----------------+
| prod_id | quantity | item_price | expanded_price |
+---------+----------+------------+----------------+
| ANV01   |       10 |       5.99 |          59.90 |
| ANV02   |        3 |       9.99 |          29.97 |
| TNT2    |        5 |      10.00 |          50.00 |
| FB      |        1 |      10.00 |          10.00 |
+---------+----------+------------+----------------+

第11章:使用数据处理函数

SQL支持类型的函数:

  1. 用于处理文本串的文本函数;
  2. 用于在数值数据上进行算数操作的数值函数;
  3. 用于处理热气和时间值并从这些值中提取特定成分的日期和时间函数;
  4. 返回DBMS正是用的特殊信息的系统函数;

文本处理函数:

关键字:upper()

作用:将文本转换成大写

select vend_name,Upper(vend_name) as vend_name_upase from vendors order by vend_name;
+----------------+-----------------+
| vend_name      | vend_name_upase |
+----------------+-----------------+
| ACME           | ACME            |
| Anvils R Us    | ANVILS R US     |
| Furball Inc.   | FURBALL INC.    |
| Jet Set        | JET SET         |
| Jouets Et Ours | JOUETS ET OURS  |
| LT Supplies    | LT SUPPLIES     |
+----------------+-----------------+
6 rows in set (0.00 sec)

常用的文本处理函数:(详细解释待补充)

函数 说明
left() 返回串左边的字符
length() 返回串的长度
locate() 找出串的一个字串
lower() 将串转换成小写
LTrim() 去掉左边的空格
Right() 返回串右边的字符
RTrim() 去掉串右边的空格
Soundex() 返回串的SOUNDEX的值
SubString() 返回字串的字符
Upper() 将串转换成大写

其中SOUNDEX解释:

​ 个人理解模糊匹配相同的发音;

mysql> select cust_name , cust_contact from customers;
+----------------+--------------+
| cust_name      | cust_contact |
+----------------+--------------+
| Coyote Inc.    | Y Lee        |
| Mouse House    | Jerry Mouse  |
| Wascals        | Jim Jones    |
| Yosemite Place | Y Sam        |
| E Fudd         | E Fudd       |
+----------------+--------------+
5 rows in set (0.00 sec)

假如我们想查找Y Lee联系人,但实际我们查找输入的使L Lie,那么无法得到所需要的;

mysql> select cust_name,cust_contact from customers where cust_contact ="Y.Lie";
Empty set (0.00 sec)

我们可以使用SOUNDEX进行音节的模糊匹配:

mysql> select cust_name,cust_contact from customers where soundex(cust_contact) =soundex("Y.Lie");
+-------------+--------------+
| cust_name   | cust_contact |
+-------------+--------------+
| Coyote Inc. | Y Lee        |
+-------------+--------------+
1 row in set (0.00 sec)

日期和时间处理函数:

使用形式:大多数被用来读取、统计和处理这些值

常用日期和时间处理函数:(待补充)

使用日期格式的注意点:

  1. 不管插入还是更新还是用where进行过滤,日期格式必须yyy-mm-dd;

    mysql> select cust_id,order_num from orders where order_date ="2005-09-01";
    +---------+-----------+
    | cust_id | order_num |
    +---------+-----------+
    |   10001 |     20005 |
    +---------+-----------+
    1 row in set (0.00 sec)
    
    mysql> select * from orders;
    +-----------+---------------------+---------+
    | order_num | order_date          | cust_id |
    +-----------+---------------------+---------+
    |     20005 | 2005-09-01 00:00:00 |   10001 |
    |     20006 | 2005-09-12 00:00:00 |   10003 |
    |     20007 | 2005-09-30 00:00:00 |   10004 |
    |     20008 | 2005-10-03 00:00:00 |   10005 |
    |     20009 | 2005-10-08 00:00:00 |   10001 |
    +-----------+---------------------+---------+
    5 rows in set (0.00 sec)
    

    关键字:date()

    作用:仅提取列的日期部分

    mysql> select cust_id,order_num from orders where date(order_date) ="2005-09-01";
    +---------+-----------+
    | cust_id | order_num |
    +---------+-----------+
    |   10001 |     20005 |
    +---------+-----------+
    1 row in set (0.00 sec)
    

    日期的范围搜索:

    关键字:between and

    例:检索2005年9月下的所有订单

    mysql> select cust_id ,order_num from orders where date(order_date ) between "2005-09-01" and "2005-09-30";
    +---------+-----------+
    | cust_id | order_num |
    +---------+-----------+
    |   10001 |     20005 |
    |   10003 |     20006 |
    |   10004 |     20007 |
    +---------+-----------+
    3 rows in set (0.00 sec)
    

    解2:

    mysql> select cust_id ,order_num  from orders where Year(order_date ) = 2005 and Month(order_date )=9;
    +---------+-----------+
    | cust_id | order_num |
    +---------+-----------+
    |   10001 |     20005 |
    |   10003 |     20006 |
    |   10004 |     20007 |
    +---------+-----------+
    3 rows in set (0.00 sec)
    
    

    数值处理函数:

    定义:数值处理仅处理数值数据,一般用于代数或者几个运算;(详细解释待补充)

    第12章:汇总数据

    聚集函数:

    定义:聚集函数运行在行组上,计算和返回单个值的函数;

    函数 说明
    AVG() 返回某列的平均值
    COUNT() 返回某列的行数
    MAX() 返回某列的最大值
    MIN() 返回某列的最小值
    SUN() 返回某列值之和

    AVG()函数:

    作用:返回所有列的平均值,也可返回特定列的平均值

    mysql> select avg(prod_price) as avg_price from products;
    +-----------+
    | avg_price |
    +-----------+
    | 16.133571 |
    +-----------+
    1 row in set (0.06 sec)
    
    mysql> select prod_price  from products;
    +------------+
    | prod_price |
    +------------+
    |       5.99 |
    |       9.99 |
    |      14.99 |
    |      13.00 |
    |      10.00 |
    |       2.50 |
    |       3.42 |
    |      35.00 |
    |      55.00 |
    |       8.99 |
    |      50.00 |
    |       4.49 |
    |       2.50 |
    |      10.00 |
    +------------+
    14 rows in set (0.00 sec)
    
    

    注:

    1. 为获得多个列的平均值,必须使用多个AVG()函数;

    2. NULL值,AVG()函数忽略列值为NULL的行;

    COUNT()函数:

    两种使用方法:

    1. 使用COUNT(*)对表中行的数目进行计数,不管列表中包含的是空值还是非空值;
    2. 对特定列中具有值的行进行技术,忽略NULL值;
    #返回客户数量--行
    mysql> select count(*) from customers;
    +----------+
    | count(*) |
    +----------+
    |        5 |
    +----------+
    1 row in set (0.00 sec)
    

    统计具有电子邮件地址的客户数量:

    初始状态:

    mysql> select cust_email from customers;
    +---------------------+
    | cust_email          |
    +---------------------+
    | ylee@coyote.com     |
    | NULL                |
    | rabbit@wascally.com |
    | sam@yosemite.com    |
    | NULL                |
    +---------------------+
    5 rows in set (0.00 sec)
    

    筛选:

    mysql> select count(cust_email )from customers;
    +--------------------+
    | count(cust_email ) |
    +--------------------+
    |                  3 |
    +--------------------+
    1 row in set (0.00 sec)
    

    MAX()与MIN()函数:

    特点:都需要指定列名;

    mysql> select max(prod_price ) as max_price from products;
    +-----------+
    | max_price |
    +-----------+
    |     55.00 |
    +-----------+
    1 row in set (0.00 sec)
    
    mysql> select min(prod_price ) as min_price from products;
    +-----------+
    | min_price |
    +-----------+
    |      2.50 |
    +-----------+
    1 row in set (0.00 sec)
    

    SUM()函数:

    作用:指定列值的和

    相似:count计算行值的个数

    mysql> select sum(quantity ) as items_ordered from  orderitems where order_num = 20005;
    +---------------+
    | items_ordered |
    +---------------+
    |            19 |
    +---------------+
    1 row in set (0.00 sec)
    
    mysql> select quantity,order_num from  orderitems;
    +----------+-----------+
    | quantity | order_num |
    +----------+-----------+
    |       10 |     20005 |
    |        3 |     20005 |
    |        5 |     20005 |
    |        1 |     20005 |
    |        1 |     20006 |
    |      100 |     20007 |
    |       50 |     20008 |
    |        1 |     20009 |
    |        1 |     20009 |
    |        1 |     20009 |
    |        1 |     20009 |
    +----------+-----------+
    11 rows in set (0.00 sec)
    

    注:

    sum()函数忽略列值为NULl的行;

    聚集不同值:

    计算不同的值需要指定DISTINCT参数;

    mysql> select avg(distinct prod_price ) as avg_price from products where vend_id =1003;
    +-----------+
    | avg_price |
    +-----------+
    | 15.998000 |
    +-----------+
    1 row in set (0.00 sec)
    

    作用的函数:count(),但是不能用于count(*)

    distinct()必须用于列名,不能用于计算或者表达式;

    组合聚集函数:

    mysql> select count(*) as num_items,min(prod_price ) as price_min,max(prod_price ) as price_max
        -> ,avg(prod_price ) as price_avg from products;
    +-----------+-----------+-----------+-----------+
    | num_items | price_min | price_max | price_avg |
    +-----------+-----------+-----------+-----------+
    |        14 |      2.50 |     55.00 | 16.133571 |
    +-----------+-----------+-----------+-----------+
    1 row in set (0.00 sec)
    
posted @ 2020-09-23 21:59  Xbhog  阅读(808)  评论(2编辑  收藏  举报