MYSQL数据库学习(二):结构化查询语言

1 数据库简介

1.1 数据存储

现代数据存储的主要手段:

  • 文件: 使用简单; 缺点:对于数据容量较大的数据,不能很好地满足,性能较差;不易扩展
  • 数据库:持久化存储;读写速度高;保证数据的有效性;对程序的支持性号,容易扩展

1.2 数据库

数据库是一种特殊的文件,其中存储着需要的数据

关系型数据库核心元素:

  • 数据行(记录)
  • 数据列(字段)
  • 数据表(数据行的集合)
  • 数据库(数据表的集合)

1.3 RDBMS

Relational Database Management System,通过表来表示关系型

  • 当前主要使用两种类型的数据库: 关系型数据库非关系型数据库,这里讨论关系型数据库

  • 关系型数据库RDBMS是建立在关系模型基础上哪个的数据库,借助集合代数等现代数学概念和方法类处理数据库中的数据

  • 关系型数据库的主要产品:

    oracle:在大型项目使用,银行,电信等项目
    mysql:web时代最常用的关系型数据库
    ms sql server:在微软项目中使用
    sqlite:轻量级数据库,主要应用在移动平台

1.4 SQL

SQL结构化查询语言是一种操作RDBMS的数据库语言,当前的关系型数据库都支持进行SQL语言操作,亚就是说可以通过SQL操作oracle,sql server,mysql,sqlite等所有的关系型数据库。

  • SQL语言主要分为:
    DQL:数据化查询语言,对数据库进行查询如select
    DML:数据库操作语言,对数据库进行增、删、改,如:insert、delete、updata
    TPL:事务处理语言,对事务进行处理,包括begin transaction,commit,rollback
    DCL:数据控制语言,进行授权和权限回收,如grant、revoke
    DDL:数据定义语言,进行数据库、表的管理等,如create、drop
    CCL:指针控制语言,通过控制指针完成表的操作,如declare cursor
  • 对于web开发程序员来说,重点在数据库的crud(增删改查),熟练编写DQL、DML,能够编写DDL完成数据库、表的操作
  • 不区分大小写

1.5 MySQL特点

  • 使用C和C++编写,并使用了多种编译器进行测试,保证源代码的可移植性

  • 支持多种操作系统,如Linux、Windows、AIX、FreeBSD、HP-UX、MacOS、NovellNetware、OpenBSD、OS/2 Wrap、Solaris等

  • 为多种编程语言提供了API,如C、C++、Python、Java、Perl、PHP、Eiffel、Ruby等

  • 支持多线程,充分利用CPU资源

  • 优化的SQL查询算法,有效地提高查询速度

  • 提供多语言支持,常见的编码如GB2312、BIG5、UTF8

  • 提供TCP/IP、ODBC和JDBC等多种数据库连接途径

  • 提供用于管理、检查、优化数据库操作的管理工具

  • 大型的数据库。可以处理拥有上千万条记录的大型数据库

  • 支持多种存储引擎

  • MySQL 软件采用了双授权政策,它分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库

  • MySQL使用标准的SQL数据语言形式

  • Mysql是可以定制的,采用了GPL协议,你可以修改源码来开发自己的Mysql系统

  • 在线DDL更改功能

  • 复制全局事务标识

  • 复制无崩溃从机

  • 复制多线程从机

  • 开源免费使用范围广,跨平台支持性好,提供了多种语言调用的API

2 数据完整性

  • 一个数据库就是一个完整的业务单元,可以包含多张表,数据被存储在表中
  • 在表中为了更加准确的存储数据,保证数据的正确有效,可以在创建表的时候,为表添加一些强制性的验证,包括数据字段的类型、约束

使用数据类型的原则是:够用就行,尽量使用取值范围小的,而不用大的,这样可以更多的节省存储空间

2.1 常用数据类型

  • 整数:int,bit
  • 小数:decimal
  • 字符串:varchar,char
  • 日期时间: date, time, datetime
  • 枚举类型(enum)

特别说明的类型如下:
decimal表示浮点数,如decimal(5,2)表示共存5位数,小数占2位
char表示固定长度的字符串,如char(3),如果填充’ab’时会补一个空格为’ab ’
varchar表示可变长度的字符串,如varchar(3),填充’ab’时就会存储’ab’
字符串text表示存储大文本,当字符大于4000时推荐使用
对于图片、音频、视频等文件,不存储在数据库中,而是上传到某个服务器上,然后在表中存储这个文件的保存路径

2.2 约束

  • 主键primary key:物理上存储的顺序
  • 非空not null:此字段不允许填写空值
  • 惟一unique:此字段的值不允许重复
  • 默认default:当不填写此值时会使用默认值,如果填写时以填写为准
  • 外键foreign key:对关系字段进行约束,当为关系字段填写值时,会到关联的表中查询此值是否存在,如果存在则填写成功,如果不存在则填写失败并抛出异常

说明:虽然外键约束可以保证数据的有效性,但是在进行数据的crud(增加、修改、删除、查询)时,都会降低数据库的性能,所以不推荐使用,那么数据的有效性怎么保证呢?答:可以在逻辑层进行控制

2.3 数值类型(常用)

类型字节大小有符号范围(Signed)无符号范围(Unsigned)
TINYINT1-128 ~ 1270 ~ 255
SMALLINT2-32768 ~ 327670 ~ 65535
MEDIUMINT3-8388608 ~ 83886070 ~ 16777215
INT/INTEGER4-2147483648 ~21474836470 ~ 4294967295
BIGINT8-9223372036854775808 ~ 92233720368547758070 ~ 18446744073709551615

2.3.1 字符串

类型字节大小示例
CHAR0-255类型:char(3) 输入’ab’, 实际存储为’ab ‘, 输入’abcd’ 实际存储为’abc’
VARCHAR0-255类型:varchar(3) 输’ab’,实际存储为’ab’, 输入’abcd’,实际存储为’abc’
TEXT0-65535大文本

2.3.2 日期时间类型

类型字节大小示例
DATE4‘2020-01-01’
TIME3‘12:29:59’
DATETIME8‘2020-01-01 12:29:59’
YEAR1‘2017’
TIMESTAMP4‘1970-01-01 00:00:01’ UTC ~ ‘2038-01-01 00:00:01’ UTC

3 数据库的命令行操作

3.1 数据库操作

  • 查看所有数据库show databases;
[root@localhost ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 23
Server version: 8.0.21 Source distribution

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| foo                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)


  • 使用数据库``use 数据库名;
mysql> use foo;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

  • 查看当前使用数据库select database();
mysql> select database();
+------------+
| database() |
+------------+
| foo        |
+------------+
1 row in set (0.00 sec)

mysql>
  • 创建数据库create database 数据库名 charset=utf-8;
mysql> create database test charset=utf-8;
ERROR 1115 (42000): Unknown character set: 'utf'
mysql> create database test charset=utf8;
Query OK, 1 row affected, 1 warning (0.48 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| foo                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
6 rows in set (0.00 sec)


  • 删除数据库drop database test;
mysql> drop database test;
Query OK, 0 rows affected (0.42 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| foo                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql>

3.2 数据表操作

  • 查看当前数据库所有show tables;

  • 查看表结构 desc 表名

mysql> desc children;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| childno | int(11)     | NO   | PRI | NULL    | auto_increment |
| fname   | varchar(30) | YES  |     | NULL    |                |
| age     | int(11)     | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql>

3.2.1 创建表

CREATE TABLE table_name(
    column1 datatype contrai,
    column2 datatype,
    column3 datatype,
    .....
    columnN datatype,
    PRIMARY KEY(one or more columns)
);

例:创建班级表

mysql> create table classes(
    ->     id int unsigned auto_increment primary key not null,
    ->     name varchar(10)
    -> );
Query OK, 0 rows affected (0.37 sec)

mysql> show tables;
+---------------+
| Tables_in_foo |
+---------------+
| children      |
| classes       |
+---------------+
2 rows in set (0.00 sec)

例:创建学生表

mysql> create table students(
    ->     id int unsigned primary key auto_increment not null,
    ->     name varchar(20) default '',
    ->     age tinyint unsigned default 0,
    ->     height decimal(5,2),
    ->     gender enum('男','女','人妖','保密'),
    ->     cls_id int unsigned default 0
    -> );
Query OK, 0 rows affected (0.66 sec)

mysql> show tables;
+---------------+
| Tables_in_foo |
+---------------+
| children      |
| classes       |
| students      |
+---------------+
3 rows in set (0.00 sec)

mysql> 

3.2.2 修改表

使用ALTER TABLE要极为小心,应该在进行改动前做一个完整的备份(模式和数据的备份)。数据库的更改不能撤销,如果增加了不需要的列可能不能删除它们。类似的,如果删除了不该删除的列,可能会丢失该列中的所有数据

修改表-添加字段
alter table 表名 add 列名 类型;
例:

mysql> desc students;
+--------+-------------------------------------+------+-----+---------+----------------+
| Field  | Type                                | Null | Key | Default | Extra          |
+--------+-------------------------------------+------+-----+---------+----------------+
| id     | int unsigned                        | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)                         | YES  |     |         |                |
| age    | tinyint unsigned                    | YES  |     | 0       |                |
| height | decimal(5,2)                        | YES  |     | NULL    |                |
| gender | enum('男','女','人妖','保密')       | YES  |     | NULL    |                |
| cls_id | int unsigned                        | YES  |     | 0       |                |
+--------+-------------------------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

mysql> alter table students add birthday datetime;
Query OK, 0 rows affected (0.25 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc students;
+----------+-------------------------------------+------+-----+---------+----------------+
| Field    | Type                                | Null | Key | Default | Extra          |
+----------+-------------------------------------+------+-----+---------+----------------+
| id       | int unsigned                        | NO   | PRI | NULL    | auto_increment |
| name     | varchar(20)                         | YES  |     |         |                |
| age      | tinyint unsigned                    | YES  |     | 0       |                |
| height   | decimal(5,2)                        | YES  |     | NULL    |                |
| gender   | enum('男','女','人妖','保密')       | YES  |     | NULL    |                |
| cls_id   | int unsigned                        | YES  |     | 0       |                |
| birthday | datetime                            | YES  |     | NULL    |                |
+----------+-------------------------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

mysql>

修改表-修改字段:重命名.

alter table 表名 change 原名 新名 类型及约束;
例:

mysql> alter table students change birthday birth datetime not null;
Query OK, 0 rows affected (1.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc students;
+--------+-------------------------------------+------+-----+---------+----------------+
| Field  | Type                                | Null | Key | Default | Extra          |
+--------+-------------------------------------+------+-----+---------+----------------+
| id     | int unsigned                        | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)                         | YES  |     |         |                |
| age    | tinyint unsigned                    | YES  |     | 0       |                |
| height | decimal(5,2)                        | YES  |     | NULL    |                |
| gender | enum('男','女','人妖','保密')       | YES  |     | NULL    |                |
| cls_id | int unsigned                        | YES  |     | 0       |                |
| birth  | datetime                            | NO   |     | NULL    |                |
+--------+-------------------------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

修改表-修改字段:不重命名

alter table 表名 modify 列名 类型及约束;
例:

mysql> alter table students modify birth date not null;
Query OK, 0 rows affected (0.79 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc students;
+--------+-------------------------------------+------+-----+---------+----------------+
| Field  | Type                                | Null | Key | Default | Extra          |
+--------+-------------------------------------+------+-----+---------+----------------+
| id     | int unsigned                        | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)                         | YES  |     |         |                |
| age    | tinyint unsigned                    | YES  |     | 0       |                |
| height | decimal(5,2)                        | YES  |     | NULL    |                |
| gender | enum('男','女','人妖','保密')       | YES  |     | NULL    |                |
| cls_id | int unsigned                        | YES  |     | 0       |                |
| birth  | date                                | NO   |     | NULL    |                |
+--------+-------------------------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

修改表-删除字段

alter table 表名 drop 列名;
例:

mysql> alter table students drop birth;
Query OK, 0 rows affected (0.93 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc students;
+--------+-------------------------------------+------+-----+---------+----------------+
| Field  | Type                                | Null | Key | Default | Extra          |
+--------+-------------------------------------+------+-----+---------+----------------+
| id     | int unsigned                        | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)                         | YES  |     |         |                |
| age    | tinyint unsigned                    | YES  |     | 0       |                |
| height | decimal(5,2)                        | YES  |     | NULL    |                |
| gender | enum('男','女','人妖','保密')       | YES  |     | NULL    |                |
| cls_id | int unsigned                        | YES  |     | 0       |                |
+--------+-------------------------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

3.2.3 删除表

drop table 表名;

mysql> drop table students;
Query OK, 0 rows affected (0.27 sec)

mysql> show tables;
+---------------+
| Tables_in_foo |
+---------------+
| children      |
| classes       |
+---------------+
2 rows in set (0.00 sec)

查看创建语句

show create table 表名;

mysql> show create table classes;
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                     |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| classes | CREATE TABLE `classes` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

4 数据的增删改查

CURD:

  • C:创建Create
  • U:更新Update
  • R:读取Retrieve
  • D:删除Delete

4.1 查询(基本)

查询所有列:

select * from 表名

mysql> select * from children;
+---------+--------+------+
| childno | fname  | age  |
+---------+--------+------+
|       1 | Ann    |    4 |
|       2 | Tom    |   13 |
|       3 | Harry  |   17 |
|       4 | Robert |    7 |
+---------+--------+------+
4 rows in set (0.05 sec)

查询指定列:

select 列1,列2 from 表名;

mysql> select childno from children;
+---------+
| childno |
+---------+
|       1 |
|       2 |
|       3 |
|       4 |
+---------+
4 rows in set (0.00 sec)

mysql> select childno as no from children;  # 为列childno指定别名no查询对应列
+----+
| no |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
+----+
4 rows in set (0.00 sec)

4.2 增加

格式:INSERT [INTO] tb_name [(co​​l_name,...)] {VALUES | VALUE} ({expr | DEFAULT},...),(...),...;

说明:主键列是自动增长,但是在全列插入时需要占位,通常使用0或者default 或者null 来占位,插入成功后以实际数据为准

  • 全列插入:值的顺序与表中字段的顺序对应

    insert into 表名 values(...)
    例:

mysql> desc students;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | int unsigned     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20)      | YES  |     |         |                |
| age    | tinyint unsigned | YES  |     | 18      |                |
| gender | enum('m','f')    | YES  |     | NULL    |                |
| cls_id | int unsigned     | YES  |     | 0       |                |
+--------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql> insert into students value('zhangsan',20,'m');
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into students value('zhangsan',20,'m',0);
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into students value(0,'zhangsan',20,'m',0);
Query OK, 1 row affected (0.07 sec)

mysql> select * from students;
+----+----------+------+--------+--------+
| id | name     | age  | gender | cls_id |
+----+----------+------+--------+--------+
|  1 | zhangsan |   20 | m      |      0 |
+----+----------+------+--------+--------+
1 row in set (0.00 sec)
  • 部分列插入:值的顺序与给出的列顺序对应
    insert into 表名(列1,...) values(值1,...)
    例:
mysql> insert into students(name,gender) values('lisi','m');
Query OK, 1 row affected (0.08 sec)

mysql> select * from students;
+----+----------+------+--------+--------+
| id | name     | age  | gender | cls_id |
+----+----------+------+--------+--------+
|  1 | zhangsan |   20 | m      |      0 |
|  2 | lisi     |   18 | m      |      0 |
+----+----------+------+--------+--------+
2 rows in set (0.00 sec)

上面的语句一次可以向表中插入一行数据,还可以一次性插入多行数据,这样可以减少与数据库的通信

全列多行插入:值的顺序与给出的列顺序对应

方式1:insert into 表名 values(...),(...)...;
例:

mysql> insert into classes values(0,'math'),(0,'art');
Query OK, 2 rows affected (0.38 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from classes;
+----+---------+
| id | name    |
+----+---------+
|  1 | python1 |
|  2 | python2 |
|  3 | math    |
|  4 | art     |
+----+---------+
4 rows in set (0.00 sec)

方式2:insert into 表名(列1,...) values(值1,...),(值1,...)...;

例:

mysql> insert into students(name) values('wangwu'),('zhaoliu'),('laoba');
Query OK, 3 rows affected (0.09 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from students;
+----+----------+------+--------+--------+
| id | name     | age  | gender | cls_id |
+----+----------+------+--------+--------+
|  1 | zhangsan |   20 | m      |      0 |
|  2 | lisi     |   18 | m      |      0 |
|  3 | wangwu   |   18 | NULL   |      0 |
|  4 | zhaoliu  |   18 | NULL   |      0 |
|  5 | laoba    |   18 | NULL   |      0 |
+----+----------+------+--------+--------+
5 rows in set (0.00 sec)

4.3 修改

update 表名 set 列1=值1,列2=值2... where 条件

例:

mysql> select * from students;
+----+----------+------+--------+--------+
| id | name     | age  | gender | cls_id |
+----+----------+------+--------+--------+
|  1 | zhangsan |   20 | m      |      0 |
|  2 | lisi     |   18 | m      |      0 |
|  3 | wangwu   |   18 | NULL   |      0 |
|  4 | zhaoliu  |   18 | NULL   |      0 |
|  5 | laoba    |   18 | NULL   |      0 |
+----+----------+------+--------+--------+
5 rows in set (0.00 sec)

mysql> update students set gender='m',age=28 where id=5;
Query OK, 1 row affected (0.35 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from students;
+----+----------+------+--------+--------+
| id | name     | age  | gender | cls_id |
+----+----------+------+--------+--------+
|  1 | zhangsan |   20 | m      |      0 |
|  2 | lisi     |   18 | m      |      0 |
|  3 | wangwu   |   18 | NULL   |      0 |
|  4 | zhaoliu  |   18 | NULL   |      0 |
|  5 | laoba    |   28 | m      |      0 |
+----+----------+------+--------+--------+
5 rows in set (0.00 sec)

4.4 删除

delete from 表名 where 条件
例:

mysql> delete from students where id=5;
Query OK, 1 row affected (0.35 sec)

mysql> select * from students;
+----+----------+------+--------+--------+
| id | name     | age  | gender | cls_id |
+----+----------+------+--------+--------+
|  1 | zhangsan |   20 | m      |      0 |
|  2 | lisi     |   18 | m      |      0 |
|  3 | wangwu   |   18 | NULL   |      0 |
|  4 | zhaoliu  |   18 | NULL   |      0 |
+----+----------+------+--------+--------+
4 rows in set (0.00 sec

逻辑删除,本质就是修改操作(安全删除,可以找回):
update students set isdelete=1 where id=1;
需要表中设置一个isdelete的字段。

5 数据的备份和恢复

备份:mysqldump -uroot -p 数据库名 > 备份名.sql;

[root@localhost ~]# mysqldump -uroot -p foo > test.sql;
Enter password: 
[root@localhost ~]# ls
anaconda-ks.cfg  Documents  initial-setup-ks.cfg  Pictures  Templates  Videos
Desktop          Downloads  Music                 Public    test.sql
[root@localhost ~]#

恢复

step1:连接mysql,创建新的数据库
step2:退出连接,执行命令`mysql -uroot -p 新数据库名 < 备份名.sql`
mysql> create database newfoo; # 连接mysql,创建新的数据库
Query OK, 1 row affected (0.12 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| foo                |
| information_schema |
| mysql              |
| newfoo             |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql> use newfoo;
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql> quit # 退出连接
Bye

[root@localhost ~]# mysql -uroot -p newfoo < test.sql;  # 执行命令`mysql -uroot -p 新数据库名 < 备份名.sql`
Enter password: 
[root@localhost ~]# show databases;
bash: show: command not found...
[root@localhost ~]# mysql -uroot -p
Enter password:

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| foo                |
| information_schema |
| mysql              |
| newfoo             |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql> use newfoo;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+------------------+
| Tables_in_newfoo |
+------------------+
| children         |
| classes          |
| students         |
+------------------+
3 rows in set (0.00 sec

6 mysql的查询

6.1 数据准备

6.1.1 创建数据库、数据表

  • 创建数据库
    create database foo charset=utf8;

  • 使用数据库
    use foo;

  • students表
    create table students(
    id int unsigned primary key auto_increment not null,
    name varchar(20) default ‘’,
    age tinyint unsigned default 0,
    height decimal(5,2),
    gender enum(‘男’,‘女’,‘中性’,‘保密’) default ‘保密’,
    cls_id int unsigned default 0,
    is_delete bit default 0
    );

– classes表
create table classes (
id int unsigned auto_increment primary key not null,
name varchar(30) not null
);

6.1.2 准备数据

  • 向students表中插入数据
mysql> insert into students values
    -> (0,'小明',18,180.00,2,1,0),
    -> (0,'小月月',18,180.00,2,2,1),
    -> (0,'彭于晏',29,185.00,1,1,0),
    -> (0,'刘德华',59,175.00,1,2,1),
    -> (0,'黄蓉',38,160.00,2,1,0),
    -> (0,'凤姐',28,150.00,4,2,1),
    -> (0,'王祖贤',18,172.00,2,1,1),
    -> (0,'周杰伦',36,NULL,1,1,0),
    -> (0,'程坤',27,181.00,1,2,0),
    -> (0,'刘亦菲',25,166.00,2,2,0),
    -> (0,'金星',33,162.00,3,3,1),
    -> (0,'静香',12,180.00,2,4,0),
    -> (0,'郭靖',12,170.00,1,4,0),
    -> (0,'周杰',34,176.00,2,5,0);
Query OK, 14 rows affected (0.08 sec)
Records: 14  Duplicates: 0  Warnings: 0
  • 向classes表中插入数据
mysql> insert into classes values(0,'math'),(0,'art');
Query OK, 2 rows affected (0.38 sec)
Records: 2  Duplicates: 0  Warnings: 0

6.2 基本查询操作

6.2.1 查询所有字段

select * from 表名;
例:

mysql> select * from students;
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |
|  2 | 小月月    |   18 | 180.00 ||      2 | 0x01                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
|  6 | 凤姐      |   28 | 150.00 | 保密   |      2 | 0x01                 |
|  7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |
| 11 | 金星      |   33 | 162.00 | 中性   |      3 | 0x01                 |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
14 rows in set (0.00 sec)

6.2.2 查询指定字段

select 列1,列2,… from 表名;
例:

mysql> select name from students;
+-----------+
| name      |
+-----------+
| 小明      |
| 小月月    |
| 彭于晏    |
| 刘德华    |
| 黄蓉      |
| 凤姐      |
| 王祖贤    |
| 周杰伦    |
| 程坤      |
| 刘亦菲    |
| 金星      |
| 静香      |
| 郭靖      |
| 周杰      |
+-----------+
14 rows in set (0.00 sec)

6.2.3 使用 as 给字段起别名

mysql> select id as 序号, name as 名字, gender as 性别 from students;
+--------+-----------+--------+
| 序号   | 名字      | 性别   |
+--------+-----------+--------+
|      1 | 小明      ||
|      2 | 小月月    ||
|      3 | 彭于晏    ||
|      4 | 刘德华    ||
|      5 | 黄蓉      ||
|      6 | 凤姐      | 保密   |
|      7 | 王祖贤    ||
|      8 | 周杰伦    ||
|      9 | 程坤      ||
|     10 | 刘亦菲    ||
|     11 | 金星      | 中性   |
|     12 | 静香      ||
|     13 | 郭靖      ||
|     14 | 周杰      ||
+--------+-----------+--------+
14 rows in set (0.00 sec)

6.2.4 表名.字段名

mysql> select students.id,students.name,students.gender from students;
+----+-----------+--------+
| id | name      | gender |
+----+-----------+--------+
|  1 | 小明      ||
|  2 | 小月月    ||
|  3 | 彭于晏    ||
|  4 | 刘德华    ||
|  5 | 黄蓉      ||
|  6 | 凤姐      | 保密   |
|  7 | 王祖贤    ||
|  8 | 周杰伦    ||
|  9 | 程坤      ||
| 10 | 刘亦菲    ||
| 11 | 金星      | 中性   |
| 12 | 静香      ||
| 13 | 郭靖      ||
| 14 | 周杰      ||
+----+-----------+--------+
14 rows in set (0.00 sec)

6.2.5 可以通过 as 给表起别名

mysql> select s.id,s.name,s.gender from students as s;
+----+-----------+--------+
| id | name      | gender |
+----+-----------+--------+
|  1 | 小明      ||
|  2 | 小月月    ||
|  3 | 彭于晏    ||
|  4 | 刘德华    ||
|  5 | 黄蓉      ||
|  6 | 凤姐      | 保密   |
|  7 | 王祖贤    ||
|  8 | 周杰伦    ||
|  9 | 程坤      ||
| 10 | 刘亦菲    ||
| 11 | 金星      | 中性   |
| 12 | 静香      ||
| 13 | 郭靖      ||
| 14 | 周杰      ||
+----+-----------+--------+
14 rows in set (0.00 sec)

6.2.6 消除重复行

在select后面列前使用distinct可以消除重复的行
select distinct 列1,... from 表名;
例:

mysql> select distinct gender from students;
+--------+
| gender |
+--------+
||
||
| 保密   |
| 中性   |
+--------+
4 rows in set (0.00 sec)

6.3 条件查询

6.3.1 条件查询的语法

使用where字句对表中的数据筛选,结果为true的行会出现在结果集中

语法格式:select * from 表名 where 条件

mysql> select * from students where id=1;
+----+--------+------+--------+--------+--------+----------------------+
| id | name   | age  | height | gender | cls_id | is_delete            |
+----+--------+------+--------+--------+--------+----------------------+
|  1 | 小明   |   18 | 180.00 ||      1 | 0x00                 |
+----+--------+------+--------+--------+--------+----------------------+
1 row in set (0.13 sec)

mysql>

6.3.2 比较运算符

  • 等于 =
  • 大于 >
  • 大于等于 >=
  • 小于 <
  • 小于等于 <=
  • 不等于 != 或 <>
mysql> select * from students where id>3;       # 查寻编号大于3的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
|  6 | 凤姐      |   28 | 150.00 | 保密   |      2 | 0x01                 |
|  7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |
| 11 | 金星      |   33 | 162.00 | 中性   |      3 | 0x01                 |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
11 rows in set (0.04 sec)

mysql> select * from students where id<=4;  # 查询编号小于等于4的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |
|  2 | 小月月    |   18 | 180.00 ||      2 | 0x01                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
+----+-----------+------+--------+--------+--------+----------------------+
4 rows in set (0.00 sec)

mysql> select * from students where name != '静香';     # 查询名字不叫‘静香’的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |
|  2 | 小月月    |   18 | 180.00 ||      2 | 0x01                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
|  6 | 凤姐      |   28 | 150.00 | 保密   |      2 | 0x01                 |
|  7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |
| 11 | 金星      |   33 | 162.00 | 中性   |      3 | 0x01                 |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
13 rows in set (0.00 sec)

mysql> select * from students where is_delete=0;    # 查询没有被删除(逻辑删除)的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
9 rows in set (0.00 sec)

6.3.3 逻辑运算符

  • and
  • or
  • not
mysql> select * from students where id > 3 and gender='女'; # 查询编号大于3的女学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
|  7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
5 rows in set (0.00 sec)

mysql> select * from students where id < 4 or is_delete=0;  # 查询编号小于4或没有被删除的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |
|  2 | 小月月    |   18 | 180.00 ||      2 | 0x01                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
10 rows in set (0.00 sec)

6.3.4 模糊查询

  • like
  • % 表示任意多个字符
  • _ 表示一个任意的字符
mysql> select * from students where name like '周%';    # 查询姓周的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
2 rows in set (0.00 sec)

mysql> select * from students where name like '周_'; # 查询姓周而且名只有一个字的学生
+----+--------+------+--------+--------+--------+----------------------+
| id | name   | age  | height | gender | cls_id | is_delete            |
+----+--------+------+--------+--------+--------+----------------------+
| 14 | 周杰   |   34 | 176.00 ||      5 | 0x00                 |
+----+--------+------+--------+--------+--------+----------------------+
1 row in set (0.00 sec)

mysql> select * from students where name like '黄%' or name like '%靖'; # 查询姓黄的学生或叫 什么什么靖的学生
+----+--------+------+--------+--------+--------+----------------------+
| id | name   | age  | height | gender | cls_id | is_delete            |
+----+--------+------+--------+--------+--------+----------------------+
|  5 | 黄蓉   |   38 | 160.00 ||      1 | 0x00                 |
| 13 | 郭靖   |   12 | 170.00 ||      4 | 0x00                 |
+----+--------+------+--------+--------+--------+----------------------+
2 rows in set (0.00 sec)

6.3.5 范围查询

  • in 表示在一个非连续的范围 貌似非连续范围需要用()括起来
  • between … and … 表示在一个连续范围
mysql> select * from students where id in (1,3,8);  # 查看编号为1,3,8的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
3 rows in set (0.00 sec)

mysql> select * from students where id in 1,3,8;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1,3,8' at line 1
mysql> select * from students where id in 1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1' at line 1
mysql> select * from students where id in (1);
+----+--------+------+--------+--------+--------+----------------------+
| id | name   | age  | height | gender | cls_id | is_delete            |
+----+--------+------+--------+--------+--------+----------------------+
|  1 | 小明   |   18 | 180.00 ||      1 | 0x00                 |
+----+--------+------+--------+--------+--------+----------------------+
1 row in set (0.00 sec)

mysql> select * from students where id between 3 and 8; # 查询编号3到8的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
|  6 | 凤姐      |   28 | 150.00 | 保密   |      2 | 0x01                 |
|  7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
6 rows in set (0.00 sec)

mysql> select * from students where (id between 3 and 8) and gender='男';   # 查询编号在3到8的男学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
3 rows in set (0.00 sec)

6.3.6 空判断

  • null 与 ‘’ 是不同的
  • 判空 is null
  • 判非空 is not null
mysql> select * from students where height is null; # 查询没有填写身高的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
1 row in set (0.00 sec)

mysql> select * from students where height is not null; # 查询填写了身高的学生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |
|  2 | 小月月    |   18 | 180.00 ||      2 | 0x01                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
|  6 | 凤姐      |   28 | 150.00 | 保密   |      2 | 0x01                 |
|  7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |
| 11 | 金星      |   33 | 162.00 | 中性   |      3 | 0x01                 |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
13 rows in set (0.00 sec)

mysql> select * from students where height is not null and gender=‘男’;  # 注意引用字符的括号应在英文输入模式下输入
ERROR 1054 (42S22): Unknown column '‘男’' in 'where clause'
mysql> select * from students where height is not null and gender='男'; # 查询填写了身高的男生
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
4 rows in set (0.00 sec)

6.3.7 优先级

  • 优先级从高到底顺序:小括号、not、比较运算符、逻辑运算符
  • and 比 or 优先运算, 如果同时出现并希望优先运算or,需要结合()

6.4 排序

语法:select * from 表名 order by 列1 asc|desc [,列2 asc|desc,...]

  • 将行数据按照列1进行排序,如果某些行列1的值相同,则按照列2排序,以此类推
  • 默认按照列值从小到大排列(asc)
  • asc 升序
  • desc 降序
mysql> select * from students where gender='男' and is_delete=0 order by id desc;   # 查询未被删除的男学生,按照学号降序排列
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
4 rows in set (0.00 sec)

mysql> select * from students where is_delete=0 order by name;  # 查询未被删除的学生,按照名字排序(升序)
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
9 rows in set (0.00 sec)

mysql> select * from students order by age desc,height desc;    # 显示所有学生信息,先按照年龄大->小,当年龄相同时按照身高 高->低 排序
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |
| 11 | 金星      |   33 | 162.00 | 中性   |      3 | 0x01                 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  6 | 凤姐      |   28 | 150.00 | 保密   |      2 | 0x01                 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |
|  2 | 小月月    |   18 | 180.00 ||      2 | 0x01                 |
|  7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
14 rows in set (0.01 sec)

6.5 聚合函数

  • 总数 count(*):计算总行数,括号中 *与列名结果是相同的
  • 最大值 max(列) :求此列最大值
  • 最小值 min(列):求此列的最小值
  • 求和 sum(列):求此列的和
  • 平均值 avg(列) :求此列的平均值
mysql> select count(*) from students;   # 计算记录数(行数)
+----------+
| count(*) |
+----------+
|       14 |
+----------+
1 row in set (0.00 sec)

mysql> select max(id) from students where gender='女';  # 计算女生的最大编号
+---------+
| max(id) |
+---------+
|      14 |
+---------+
1 row in set (0.00 sec)

mysql> select min(id) from students where is_delete=0;  # 计算未被删除的学生最小编号
+---------+
| min(id) |
+---------+
|       1 |
+---------+
1 row in set (0.00 sec)

mysql> select sum(age) from students where gender='女'; # 计算女生年龄综合
+----------+
| sum(age) |
+----------+
|      163 |
+----------+
1 row in set (0.00 sec)

mysql> select sum(age)/count(*) from students where gender='女';    # 计算女生平均年龄
+-------------------+
| sum(age)/count(*) |
+-------------------+
|           23.2857 |
+-------------------+
1 row in set (0.00 sec)

mysql> select avg(id) from students where is_delete=0 and gender='女';  # 计算为别删除的女生平均年龄
+---------+
| avg(id) |
+---------+
|  8.4000 |
+---------+
1 row in set (0.00 sec)

6.6 分组

group by

  • group by的含义:将查询结果按照1个或多个字段进行分组,字段值相同的为一组
  • group by可用于单个字段分组,也可用于多个字段分组
select * from students;
+----+-----------+------+--------+--------+--------+-----------+
| id | name      | age  | height | gender | cls_id | is_delete |
+----+-----------+------+--------+--------+--------+-----------+
|  1 | 小明      |   18 | 180.00 ||      1 |           |
|  2 | 小月月    |   18 | 180.00 ||      2 |          |
|  3 | 彭于晏    |   29 | 185.00 ||      1 |           |
|  4 | 刘德华    |   59 | 175.00 ||      2 |          |
|  5 | 黄蓉      |   38 | 160.00 ||      1 |           |
|  6 | 凤姐      |   28 | 150.00 | 保密   |      2 |          |
|  7 | 王祖贤    |   18 | 172.00 ||      1 |          |
|  8 | 周杰伦    |   36 |   NULL ||      1 |           |
|  9 | 程坤      |   27 | 181.00 ||      2 |           |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 |           |
| 11 | 金星      |   33 | 162.00 | 中性   |      3 |          |
| 12 | 静香      |   12 | 180.00 ||      4 |           |
| 13 | 周杰      |   34 | 176.00 ||      5 |           |
| 14 | 郭靖      |   12 | 170.00 ||      4 |           |
+----+-----------+------+--------+--------+--------+-----------+

select gender from students group by gender;
+--------+
| gender |
+--------+
||
||
| 中性   |
| 保密   |
+--------+

group by + group_concat()

group_concat(字段名) 可以作为一个输出字段来使用,
表示分组之后,根据分组结果,使用group_concat()来放置每一组的某字段的值的集合

mysql> select gender,group_concat(name) from students group by gender;
+--------+-----------------------------------------------------------+
| gender | group_concat(name)                                        |
+--------+-----------------------------------------------------------+
|| 彭于晏,刘德华,周杰伦,程坤,郭靖                            |
|| 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰                  |
| 中性   | 金星                                                      |
| 保密   | 凤姐                                                      |
+--------+-----------------------------------------------------------+
4 rows in set (0.00 sec)


select gender,group_concat(id) from students group by gender;
+--------+------------------+
| gender | group_concat(id) |
+--------+------------------+
|| 3,4,8,9,14       |
|| 1,2,5,7,10,12,13 |
| 中性   | 11               |
| 保密   | 6                |
+--------+------------------+

group by + 聚合函数

我们也可以通过聚合函数来对这个值的集合做一些操作

mysql> select gender,group_concat(age) from students group by gender;
+--------+----------------------+
| gender | group_concat(age)    |
+--------+----------------------+
|| 29,59,36,27,12       |
|| 18,18,38,18,25,12,34 |
| 中性   | 33                   |
| 保密   | 28                   |
+--------+----------------------+
4 rows in set (0.00 sec)


# 分别统计性别为男/女的人年龄平均值
mysql> select gender,avg(age) from students group by gender;
+--------+----------+
| gender | avg(age) |
+--------+----------+
||  23.2857 |
||  32.6000 |
| 保密   |  28.0000 |
| 中性   |  33.0000 |
+--------+----------+
4 rows in set (0.00 sec)

分别统计性别为男/女的人的个数
mysql> select gender,count(*) from students group by gender;
+--------+----------+
| gender | count(*) |
+--------+----------+
||        7 |
||        5 |
| 保密   |        1 |
| 中性   |        1 |
+--------+----------+
4 rows in set (0.00 sec)

group by + having

  • having 条件表达式:用来分组查询后指定一些条件来输出查询结果
  • having作用和where一样,但having只能用于group by
select gender,count(*) from students group by gender having count(*)>2;
+--------+----------+
| gender | count(*) |
+--------+----------+
||        5 |
||        7 |
+--------+----------+

group by + with rollup

with rollup 的作用是:在最后新增一行,来记录当前列里所有记录的总和

mysql> select gender,count(*) from students group by gender with rollup;
+--------+----------+
| gender | count(*) |
+--------+----------+
||        5 |
||        7 |
| 中性   |        1 |
| 保密   |        1 |
| NULL   |       14 |
+--------+----------+
5 rows in set (0.00 sec)

mysql> select gender,group_concat(age) from students group by gender with rollup;
+--------+-------------------------------------------+
| gender | group_concat(age)                         |
+--------+-------------------------------------------+
|| 29,59,36,27,12                            |
|| 18,18,38,18,25,12,34                      |
| 中性   | 33                                        |
| 保密   | 28                                        |
| NULL   | 29,59,36,27,12,18,18,38,18,25,12,34,33,28 |
+--------+-------------------------------------------+
5 rows in set (0.00 sec)

6.7 分页

当数据量过大时,在一页中查看是麻烦的事情,这时可以分页

语法:

select from 表名 limit start,count

说明:获取从start开始的count条数据

mysql> select * from students where gender=1 limit 0,3;
+----+-----------+------+--------+--------+--------+----------------------+
| id | name      | age  | height | gender | cls_id | is_delete            |
+----+-----------+------+--------+--------+--------+----------------------+
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |
+----+-----------+------+--------+--------+--------+----------------------+
3 rows in set (0.00 sec)

6.8 连接查询

当查询结果的列来源于多张表时,需要将多张表连接成一个大的数据集,再选择合适的列返回.mysql支持三种类型的连接查询,分别为:

  • 内连接查询:查询的结果为两个表匹配到的数据
  • 右连接查询:查询的结果为两个表匹配到的数据,右表特有的数据,对于左表中不存在的数据使用null填充
  • 左连接查询:查询的结果为两个表匹配到的数据,左表特有的数据,对于右表中不存在的数据使用null填充
语法

select * from 表1 inner或left或right join 表2 on 表1.列 = 表2.列
例1:使用内连接查询班级表与学生表

mysql> select * from students inner join classes on students.cls_id = classes.id;
+----+-----------+------+--------+--------+--------+----------------------+----+---------+
| id | name      | age  | height | gender | cls_id | is_delete            | id | name    |
+----+-----------+------+--------+--------+--------+----------------------+----+---------+
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |  1 | python1 |
|  2 | 小月月    |   18 | 180.00 ||      2 | 0x01                 |  2 | python2 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |  1 | python1 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |  2 | python2 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |  1 | python1 |
|  6 | 凤姐      |   28 | 150.00 | 保密   |      2 | 0x01                 |  2 | python2 |
|  7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |  1 | python1 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |  1 | python1 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |  2 | python2 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |  2 | python2 |
| 11 | 金星      |   33 | 162.00 | 中性   |      3 | 0x01                 |  3 | math    |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |  4 | art     |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |  4 | art     |
+----+-----------+------+--------+--------+--------+----------------------+----+---------+
13 rows in set (0.00 sec)

例2:使用左连接查询班级表与学生表

此处使用了as为表起别名,目的是编写简单

mysql> select * from students as s left join classes as c on s.cls_id = c.id;
+----+-----------+------+--------+--------+--------+----------------------+------+---------+
| id | name      | age  | height | gender | cls_id | is_delete            | id   | name    |
+----+-----------+------+--------+--------+--------+----------------------+------+---------+
|  1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |    1 | python1 |
|  2 | 小月月    |   18 | 180.00 ||      2 | 0x01                 |    2 | python2 |
|  3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |    1 | python1 |
|  4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |    2 | python2 |
|  5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |    1 | python1 |
|  6 | 凤姐      |   28 | 150.00 | 保密   |      2 | 0x01                 |    2 | python2 |
|  7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |    1 | python1 |
|  8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |    1 | python1 |
|  9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |    2 | python2 |
| 10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |    2 | python2 |
| 11 | 金星      |   33 | 162.00 | 中性   |      3 | 0x01                 |    3 | math    |
| 12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |    4 | art     |
| 13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |    4 | art     |
| 14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 | NULL | NULL    |
+----+-----------+------+--------+--------+--------+----------------------+------+---------+
14 rows in set (0.00 sec)

例3:使用右连接查询班级表与学生表

mysql> select * from students as s right join classes as c on s.cls_id = c.id;
+------+-----------+------+--------+--------+--------+----------------------+----+---------+
| id   | name      | age  | height | gender | cls_id | is_delete            | id | name    |
+------+-----------+------+--------+--------+--------+----------------------+----+---------+
|    8 | 周杰伦    |   36 |   NULL ||      1 | 0x00                 |  1 | python1 |
|    7 | 王祖贤    |   18 | 172.00 ||      1 | 0x01                 |  1 | python1 |
|    5 | 黄蓉      |   38 | 160.00 ||      1 | 0x00                 |  1 | python1 |
|    3 | 彭于晏    |   29 | 185.00 ||      1 | 0x00                 |  1 | python1 |
|    1 | 小明      |   18 | 180.00 ||      1 | 0x00                 |  1 | python1 |
|   10 | 刘亦菲    |   25 | 166.00 ||      2 | 0x00                 |  2 | python2 |
|    9 | 程坤      |   27 | 181.00 ||      2 | 0x00                 |  2 | python2 |
|    6 | 凤姐      |   28 | 150.00 | 保密   |      2 | 0x01                 |  2 | python2 |
|    4 | 刘德华    |   59 | 175.00 ||      2 | 0x01                 |  2 | python2 |
|    2 | 小月月    |   18 | 180.00 ||      2 | 0x01                 |  2 | python2 |
|   11 | 金星      |   33 | 162.00 | 中性   |      3 | 0x01                 |  3 | math    |
|   13 | 郭靖      |   12 | 170.00 ||      4 | 0x00                 |  4 | art     |
|   12 | 静香      |   12 | 180.00 ||      4 | 0x00                 |  4 | art     |
|   14 | 周杰      |   34 | 176.00 ||      5 | 0x00                 |  5 | pe      |
| NULL | NULL      | NULL |   NULL | NULL   |   NULL | 0x                   |  6 | sing    |
+------+-----------+------+--------+--------+--------+----------------------+----+---------+

例4:查询学生姓名及班级名称

smysql> select s.name,c.name from students as s inner join classes as c on s.cls_id = c.id;
+-----------+---------+
| name      | name    |
+-----------+---------+
| 小明      | python1 |
| 小月月    | python2 |
| 彭于晏    | python1 |
| 刘德华    | python2 |
| 黄蓉      | python1 |
| 凤姐      | python2 |
| 王祖贤    | python1 |
| 周杰伦    | python1 |
| 程坤      | python2 |
| 刘亦菲    | python2 |
| 金星      | math    |
| 静香      | art     |
| 郭靖      | art     |
+-----------+---------+
13 rows in set (0.00 sec)

6.9 自关联

设计省信息的表结构provinces

    id
    ptitle

设计市信息的表结构citys

    id
    ctitle
    proid

citys表的proid表示城市所属的省,对应着provinces表的id值

问题
能不能将两个表合成一张表呢?

思考
观察两张表发现,citys表比provinces表多一个列proid,其它列的类型都是一样的

意义
存储的都是地区信息,而且每种信息的数据量有限,没必要增加一个新表,或者将来还要存储区、乡镇信息,都增加新表的开销太大

答案:
定义表areas,结构如下

    id
    atitle
    pid

说明:
因为省没有所属的省份,所以可以填写为null
城市所属的省份pid,填写省所对应的编号id
这就是自关联,表中的某一列,关联了这个表中的另外一列,但是它们的业务逻辑含义是不一样的,城市信息的pid引用的是省信息的id
在这个表中,结构不变,可以添加区县、乡镇街道、村社区等信息
创建areas表的语句如下:

create table areas(
    aid int primary key,
    atitle varchar(20),
    pid int
);

例1:查询省的名称为“山西省”的所有城市

select city.* from areas as city
inner join areas as province on city.pid=province.aid
where province.atitle='山西省';

例2:查询市的名称为“广州市”的所有区县

select dis.* from areas as dis
inner join areas as city on city.aid=dis.pid
where city.atitle='广州市';

– 查询所有省份

select count(*) from areas where pid is null;
select * from areas where pid is null;

– 查询出山东省有哪些市

select * from areas as province inner join areas as city on city.pid=province.aid having province.atitle="山东省";
select province.atitle, city.atitle from areas as province inner join areas as city on city.pid=province.aid having province.atitle="山东省";

– 查询出青岛市有哪些县城

select province.atitle, city.atitle from areas as province inner join areas as city on city.pid=province.aid having province.atitle="青岛市";
select * from areas where pid=(select aid from areas where atitle="青岛市")

6.10 子查询

子查询

在一个select 语句中,嵌入了另外一个select 语句, 那么被嵌入的select 语句称之为子查询语句

主查询

主要查询的对象,第一条select 语句

主查询和子查询的关系

  • 子查询是嵌入到主查询中
  • 子查询是辅助主查询的,要么充当条件,要么充当数据源
  • 子查询是可以独立存在的语句,是一条完整的select 语句
子查询分类
  • 标量子查询: 子查询返回的结果是一个数据(一行一列)
  • 列子查询: 返回的结果是一列(一列多行)
  • 行子查询: 返回的结果是一行(一行多列)
标量子查询

查询班级学生平均年龄
查询大于平均年龄的学生
查询班级学生的平均身高

select * from students where age > (select avg(age) from students) #查询大于平均年龄的学生;
列级子查询

查询还有学生在班的所有班级名字
找出学生表中所有的班级id
找出班级表中对应的名字

select name from classes where id in (select cls_id from students)  # 查询还有学生在班的所有班级名字;
行级子查询

需求: 查找班级年龄最大,身高最高的学生
行元素: 将多个字段合成一个行元素,在行级子查询中会使用到行元素

select * from students where (height,age) = (select max(height),max(age) from students);

子查询中特定关键字使用: in 范围

格式: 主查询where 条件in (列子查询)

6.11 查询的总结

  • 查询的完整格式
SELECT select_expr [,select_expr,...] [
      FROM tb_name
      [WHERE 条件判断]
      [GROUP BY {col_name | postion} [ASC | DESC], ...] 
      [HAVING WHERE 条件判断]
      [ORDER BY {col_name|expr|postion} [ASC | DESC], ...]
      [ LIMIT {[offset,]rowcount | row_count OFFSET offset}]
]
  • 完整的select语句
select distinct *
from 表名
where ....
group by ... having ...
order by ...
limit start,count
  • 执行顺序为:

    from 表名
    where …
    group by …
    select distinct *
    having …
    order by …
    limit start,count

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值