结构化查询语言
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) |
---|---|---|---|
TINYINT | 1 | -128 ~ 127 | 0 ~ 255 |
SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 |
MEDIUMINT | 3 | -8388608 ~ 8388607 | 0 ~ 16777215 |
INT/INTEGER | 4 | -2147483648 ~2147483647 | 0 ~ 4294967295 |
BIGINT | 8 | -9223372036854775808 ~ 9223372036854775807 | 0 ~ 18446744073709551615 |
2.3.1 字符串
类型 | 字节大小 | 示例 |
---|---|---|
CHAR | 0-255 | 类型:char(3) 输入’ab’, 实际存储为’ab ‘, 输入’abcd’ 实际存储为’abc’ |
VARCHAR | 0-255 | 类型:varchar(3) 输’ab’,实际存储为’ab’, 输入’abcd’,实际存储为’abc’ |
TEXT | 0-65535 | 大文本 |
2.3.2 日期时间类型
类型 | 字节大小 | 示例 |
---|---|---|
DATE | 4 | ‘2020-01-01’ |
TIME | 3 | ‘12:29:59’ |
DATETIME | 8 | ‘2020-01-01 12:29:59’ |
YEAR | 1 | ‘2017’ |
TIMESTAMP | 4 | ‘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 [(col_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