首先sql操作中的关键字的是大小写不敏感的,create 和CREATE是一样的。
show databases;
CREATE DATABASE [IF NOT EXISTS] 数据库名称 [create_specification [,
create_specification] ...]
create_specification:
[DEFAULT] CHARACTER SET charset_name
[DEFAULT] COLLATE collation_name
大写的表示关键字
[] 是可选项
CHARACTER SET: 指定数据库采用的字符集
COLLATE: 指定数据库字符集的校验规则
syntax是句法的意思,就理解成语法就行。manual——手册
对我们比较重要是最后 near 'databese' at line 1
这一句,表面错误在第一行的database附近
1.创建名为db_test1的数据库
CREATE DATABASE db_test1;
2.如果系统没有db_test2的数据库,则创建一个名叫db_test2的数据库,如果有则不创建
CREATE DATABASE IF NOT EXISTS db_test2;
3.如果系统没有db_test的数据库,则创建一个使用utf8mb4字符集的db_test数据库,如果有则不创建
CREATE DATABASE IF NOT EXISTS db_test CHARACTER SET utf8mb4;
use 数据库名;
使用该数据库后会有相应的提示,表明数据库已经切换了。
DROP DATABASE [IF EXISTS] db_name;
删除操作是非常危险的!一旦删除,数据就没了,难以恢复。
数据库删除以后,内部看不到对应的数据库,里边的表和数据全部被删除
drop database if exists db_test1;
drop database if exists db_test2;
如果database 里有db_test1表就删除database.
需要操作数据库中的表时,需要先使用该数据库
CREATETABLE table_name (
field1 datatype,
field2 datatype,
field3 datatype
);
示例1:
create table stu_test (
id int,
name varchar(20) comment '姓名',
password varchar(50) comment '密码',
age int,
sex varchar(1),
birthday timestamp,
amout decimal(13,2),
resume text
);
use 数据库名;
desc 表名;
示例:
desc stu_test;
use database_name;
drop table 表名;
use database_name;
show tables;
FLOAT和DOUBLE有一个很严重的问题,表示有些数据的时候,不能精确表示(存在误差),我们都知道FLOAT,DOUBLE在底层是通过多少位的底数多少位指数这种形式去表示数据的,这样带来的好处是计算速度快,存储空间小,但是会有误差。所以此时SQL提供DECIMAL(英文原意是十进制)来保存精确小数,而其底层的保存方式类型与字符串。
CRUD 增删改查(Create(增) Restrieve(查) Updata(改) Delete(删除));
先创建一个student表
mysql> create database base1 character set utf8mb4;;
Query OK, 1 row affected (0.00 sec)
mysql> use base1;
Database changed
mysql> DROP TABLE IF EXISTS student;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE TABLE student (
-> id INT NOT NULL,
-> sn INT,
-> name VARCHAR(20),
-> qq_mail VARCHAR(20)
-> );
mysql> desc student;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| sn | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| qq_mail | varchar(20) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
Query OK, 0 rows affected (0.02 sec)
insert [into] 表名 values [列名] (值1,值2,值3.....);
实例
mysql> insert into student values(123,4456,'张三','[email protected]');
Query OK, 1 row affected (0.00 sec)
mysql> insert student (id,sn,name,qq_mail) values (123,4456,'张三','[email protected]');
Query OK, 1 row affected (0.00 sec)
注意
Incorrect string value: '\xE5\xBC\xA0\xE4\xB8\x89' for column 'name' at row 1
显示的是不正确是字符值,往往可能是表格字符集的问题,需要将整个数据库都删除,去重新建立数据库和表格,并且一定要在创建数据库时指定字符集为utf8mb4(utf8mb4比utf8更加完整,多了对emoji表情的编码)。insert [into] 表名 (列名1,列名2,列名3......) values(值1,值2,值3,......)
示例:
mysql> insert student(id,qq_mail) values (213,'[email protected]');
Query OK, 1 row affected (0.00 sec)
注意:
id INT NOT NULL,
所以id不能为空,所以id是不能系统默认创建的结果
mysql> select * from student;
+-----+------+--------+---------------+
| id | sn | name | qq_mail |
+-----+------+--------+---------------+
| 123 | 4456 | 张三 | 123456@qq.com |
| 123 | 4456 | 张三 | 123456@qq.com |
| 213 | NULL | NULL | 34567@qq.com |
+-----+------+--------+---------------+
3 rows in set (0.00 sec)
示例:
mysql> insert into student values(1,1,"李四","[email protected]"),(2,2,"李四","[email protected]");
结果
mysql> select * from student;
+-----+------+--------+---------------+
| id | sn | name | qq_mail |
+-----+------+--------+---------------+
| 123 | 4456 | 张三 | 123456@qq.com |
| 123 | 4456 | 张三 | 123456@qq.com |
| 213 | NULL | NULL | 34567@qq.com |
| 1 | 1 | 李四 | 1@qq.com |
| 2 | 2 | 李四 | 2@qq.com |
+-----+------+--------+---------------+
5 rows in set (0.00 sec)
插入时间是通过特定的时间日期来表示时间日期的.
形如
‘2023-02-17 21:25:20’
示例
mysql> create table homework(id int,createTime datetime);
Query OK, 0 rows affected (0.03 sec)
mysql> insert into homework values(1,'2023-12-25 18:32:16');
Query OK, 1 row affected (0.00 sec)
mysql> select * from homework;
+------+---------------------+
| id | createTime |
+------+---------------------+
| 1 | 2023-12-25 18:32:16 |
+------+---------------------+
1 row in set (0.00 sec)
同时SQL还提供now()函数来返回当前时间。
示例:
mysql> insert into homework values(2,now());
Query OK, 1 row affected (0.00 sec)
mysql> select * from homework;
+------+---------------------+
| id | createTime |
+------+---------------------+
| 1 | 2023-12-25 18:32:16 |
| 2 | 2023-06-02 12:04:26 |
+------+---------------------+
2 rows in set (0.00 sec)
select * from 表名
在实际操作中执行select * 是非常危险的,因为实际项目中的数据量是非常大的,如果数据全部从服务器读取到客户端,数据带宽会拥堵。
select 列名,列名 from 表名;
示例:
mysql> select id,name from student;
+-----+--------+
| id | name |
+-----+--------+
| 123 | 张三 |
| 123 | 张三 |
| 213 | NULL |
| 1 | 李四 |
| 2 | 李四 |
+-----+--------+
5 rows in set (0.00 sec)
示例:
先来创建一个考试成绩表
mysql> DROP TABLE IF EXISTS exam_result;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE TABLE exam_result (
-> id INT,
-> name VARCHAR(20),
-> chinese DECIMAL(3,1),
-> math DECIMAL(3,1),
-> english DECIMAL(3,1)
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> -- 插入测试数据
mysql> INSERT INTO exam_result (id,name, chinese, math, english) VALUES
-> (1,'唐三藏', 67, 98, 56),
-> (2,'孙悟空', 87.5, 78, 77),
-> (3,'猪悟能', 88, 98.5, 90),
-> (4,'曹孟德', 82, 84, 67),
-> (5,'刘玄德', 55.5, 85, 45),
-> (6,'孙权', 70, 73, 78.5),
-> (7,'宋公明', 75, 65, 30);
Query OK, 7 rows affected (0.01 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> select * from exam_result;
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
+------+-----------+---------+------+---------+
7 rows in set (0.00 sec)
我们可以查询所有人数学成绩+10后的结果
mysql> -- 查询所有人的数学成绩+10分的结果
mysql> select math+10 from exam_result;
+---------+
| math+10 |
+---------+
| 108.0 |
| 88.0 |
| 108.5 |
| 94.0 |
| 95.0 |
| 83.0 |
| 75.0 |
+---------+
7 rows in set (0.00 sec)
但是注意:经过上述这样的查询,数据库服务器硬盘里面的数据是没有变化的。因为mysql是C/S模式,用户在客户端输入的sql,通过请求发送给服务器,服务器在解析并执行sql把查询结果从硬盘里读取出来,通过网络响应还给客户端,客户端把这些数据以临时表的形式显示出来。
其实细心的同学可以发现实际在定义exam_result
是math DECIMAL(3,1),
也就是说math这一列的数据应该是三个有效数字,且小数点后一位,但是math+10不难发现,这里第一行就是108.0这是因为这里的表是临时表。
还可以将多个列放在一起计算
比如查询每个同学的平均成绩
mysql> select name,(math+chinese+english)/3 from exam_result;
+-----------+--------------------------+
| name | (math+chinese+english)/3 |
+-----------+--------------------------+
| 唐三藏 | 73.66667 |
| 孙悟空 | 80.83333 |
| 猪悟能 | 92.16667 |
| 曹孟德 | 77.66667 |
| 刘玄德 | 61.83333 |
| 孙权 | 73.83333 |
| 宋公明 | 56.66667 |
+-----------+--------------------------+
7 rows in set (0.00 sec)
为查询结果中的列指定别名,表示返回的结果集中,以别名作为该列的名称
SELECT 表达式 [AS] 别名 [...] FROM table_name;
示例:
mysql> SELECT id, name, (chinese + math + english)/3 as 平均分 FROM exam_result;
+------+-----------+-----------+
| id | name | 平均分 |
+------+-----------+-----------+
| 1 | 唐三藏 | 73.66667 |
| 2 | 孙悟空 | 80.83333 |
| 3 | 猪悟能 | 92.16667 |
| 4 | 曹孟德 | 77.66667 |
| 5 | 刘玄德 | 61.83333 |
| 6 | 孙权 | 73.83333 |
| 7 | 宋公明 | 56.66667 |
+------+-----------+-----------+
7 rows in set (0.00 sec)
mysql> select distinct math from exam_result;
+------+
| math |
+------+
| 98.0 |
| 78.0 |
| 98.5 |
| 84.0 |
| 85.0 |
| 73.0 |
| 65.0 |
+------+
7 rows in set (0.00 sec)
distinct 也可以实现多列的去重,但是只有每列的元素值都是相同的,才会去掉,有一列不同是sql认为是不可以去重的。
此外,下面这种写法也不对
mysql> select name,(distinct mat)h from exam_result; -- 错误
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 'distinct mat)h from exam_result' at line 1
mysql> select name, distinct math from exam_result; -- 错误
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 'distinct math from exam_result' at line 1
语法:
-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...];
示例:
mysql> select * from exam_result order by math asc;
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
+------+-----------+---------+------+---------+
7 rows in set (0.00 sec)
注意:
mysql> select *,(math+chinese+english) as 总分 from exam_result order by math desc;
+------+-----------+---------+------+---------+--------+
| id | name | chinese | math | english | 总分 |
+------+-----------+---------+------+---------+--------+
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 | 276.5 |
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 | 221.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 | 185.5 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 | 233.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 | 242.5 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 | 221.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 | 170.0 |
+------+-----------+---------+------+---------+--------+
7 rows in set (0.00 sec)
mysql> select *,(math+chinese+english) as 总分 from exam_result order by 总分 desc;
+------+-----------+---------+------+---------+--------+
| id | name | chinese | math | english | 总分 |
+------+-----------+---------+------+---------+--------+
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 | 276.5 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 | 242.5 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 | 233.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 | 221.5 |
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 | 221.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 | 185.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 | 170.0 |
+------+-----------+---------+------+---------+--------+
7 rows in set (0.00 sec)
示例:
mysql> select * from exam_result order by math asc,chinese desc,english asc;
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
+------+-----------+---------+------+---------+
7 rows in set (0.00 sec)
比较运算符
逻辑运算符
注意:
示例:
mysql> select * from exam_result where english < 60;
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
+------+-----------+---------+------+---------+
3 rows in set (0.00 sec)
注:这行代码的底层是这样的,针对数据库的表,进行遍历,取出每一行的数据,把数据带入到条件中,看是否满足条件,如果为真就保留,如果为假,就不保留。
mysql> select name,english,chinese from exam_result where english < chinese;
+-----------+---------+---------+
| name | english | chinese |
+-----------+---------+---------+
| 唐三藏 | 56.0 | 67.0 |
| 孙悟空 | 77.0 | 87.5 |
| 曹孟德 | 67.0 | 82.0 |
| 刘玄德 | 45.0 | 55.5 |
| 宋公明 | 30.0 | 75.0 |
+-----------+---------+---------+
5 rows in set (0.00 sec)
mysql> select * from exam_result where english+chinese+math > 200;
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
+------+-----------+---------+------+---------+
5 rows in set (0.00 sec)
注意
看下面的代码
mysql> select name,chinese+math+english as 总分 from exam_result where 总分 > 200;
ERROR 1054 (42S22): Unknown column '总分' in 'where clause'
别名是不可以作为where条件的,这和sql的执行顺序有关,本身也是sql语法规定。上述代码的执行过程是:
1.遍历每一行;
2.把这一行带入到where的条件里去;
3.符合条件的结果,在根据select这里指定的列进行查询、计算。
但是order by 这个关键字是可以的
mysql> select name,chinese+math+english as 总分 from exam_result order by 总分 ;
+-----------+--------+
| name | 总分 |
+-----------+--------+
| 宋公明 | 170.0 |
| 刘玄德 | 185.5 |
| 唐三藏 | 221.0 |
| 孙权 | 221.5 |
| 曹孟德 | 233.0 |
| 孙悟空 | 242.5 |
| 猪悟能 | 276.5 |
+-----------+--------+
7 rows in set (0.00 sec)
示例:
mysql> -- 查询语文成绩大于80分,且英语成绩大于80分的同学
mysql> SELECT * FROM exam_result WHERE chinese > 80 and english > 80;
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
+------+-----------+---------+------+---------+
1 row in set (0.00 sec)
mysql> -- 查询语文成绩大于80分,或英语成绩大于80分的同学
mysql> SELECT * FROM exam_result WHERE chinese > 80 or english > 80;
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
+------+-----------+---------+------+---------+
3 rows in set (0.00 sec)
mysql> -- 观察AND 和 OR 的优先级:
mysql> SELECT * FROM exam_result WHERE chinese > 80 or math>70 and english > 70;
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
+------+-----------+---------+------+---------+
4 rows in set (0.00 sec)
mysql> SELECT * FROM exam_result WHERE (chinese > 80 or math>70) and english > 70;
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
+------+-----------+---------+------+---------+
3 rows in set (0.00 sec)
AND的优先级高于OR,在同时使用时,需要使用小括号()包裹优先执行的部分.
示例:
mysql> -- 查询语文成绩在 [80, 90] 分的同学及语文成绩
mysql> SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;
+-----------+---------+
| name | chinese |
+-----------+---------+
| 孙悟空 | 87.5 |
| 猪悟能 | 88.0 |
| 曹孟德 | 82.0 |
+-----------+---------+
3 rows in set (0.00 sec)
mysql> -- 使用 AND 也可以实现
mysql> SELECT name, chinese FROM exam_result WHERE chinese >= 80 AND chinese
-> <= 90;
+-----------+---------+
| name | chinese |
+-----------+---------+
| 孙悟空 | 87.5 |
| 猪悟能 | 88.0 |
| 曹孟德 | 82.0 |
+-----------+---------+
3 rows in set (0.00 sec)
示例:
mysql> -- 查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
mysql> SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);
+-----------+------+
| name | math |
+-----------+------+
| 唐三藏 | 98.0 |
+-----------+------+
1 row in set (0.00 sec)
mysql> -- 使用 OR 也可以实现
mysql> SELECT name, math FROM exam_result WHERE math = 58 OR math = 59 OR math
-> = 98 OR math = 99;
+-----------+------+
| name | math |
+-----------+------+
| 唐三藏 | 98.0 |
+-----------+------+
1 row in set (0.00 sec)
like相对于正则表达式只支持两种用法
示例:
mysql> select * from exam_result where name like '孙%';
+------+-----------+---------+------+---------+
| id | name | chinese | math | english |
+------+-----------+---------+------+---------+
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
+------+-----------+---------+------+---------+
2 rows in set (0.00 sec)
mysql> select * from exam_result where name like '孙_';
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
+------+--------+---------+------+---------+
1 row in set (0.00 sec)
在使用null作为查询条件即删选出某列为空的数据的时候可以使用 is null 和< = > null,这样的语句,但是此时要注意 = null、与< = >的区别
示例:
mysql> select * from exam_result;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
| 1 | 贾宝玉 | NULL | NULL | NULL |
+------+--------+---------+------+---------+
8 rows in set (0.00 sec)
mysql> select * from exam_result where chinese = null;
Empty set (0.00 sec)
mysql> select * from exam_result where chinese <=> null;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 贾宝玉 | NULL | NULL | NULL |
+------+--------+---------+------+---------+
1 row in set (0.00 sec)
mysql> select * from exam_result where chinese is not null;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
+------+--------+---------+------+---------+
7 rows in set (0.00 sec)
注意
select * from exam_result where Chinese = null
执行后并不会返回Chinese列等于null的行,这是因为chinese =null 执行成功后返回的就是null也就是false。也就是默认查询条件不成立,所以根本就不会筛选。
语法:
-- 起始下标为 0
-- 从 0 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;
-- 从 s 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n;
-- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;
示例:
mysql> select * from exam_result limit 3;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
+------+--------+---------+------+---------+
3 rows in set (0.00 sec)
mysql> select * from exam_result limit 3 offset 2;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
+------+--------+---------+------+---------+
3 rows in set (0.00 sec)
mysql> select * from exam_result limit 3,2;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
+------+--------+---------+------+---------+
2 rows in set (0.00 sec)
注意:limit s,n
与limit n offset s
这里面的s n 的顺序是相反的。s表示从哪开始显示,n表示显示多少行。
limit语句常常和其他查询条件语句一起用达到组合效果
示例
寻找总分前三名的学生
mysql> select id,name,chinese+math+english as 总分 from exam_result order by 总分 desc limit 3;
+------+--------+-------+
| id | name | 总分 |
+------+--------+-------+
| 3 | 猪悟能 | 276.5 |
| 2 | 孙悟空 | 242.5 |
| 4 | 曹孟德 | 233.0 |
+------+--------+-------+
3 rows in set (0.00 sec)
语法:
UPDATE table_name SET 列名1 = 数值1 [, 列名2 = 数值2 ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]
示例:
mysql> -- 将孙悟空的数学成绩变更为80分
mysql> update exam_result set math = 10 where name = "孙悟空";
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> -- 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
mysql> update exam_result set math = 60,chinese = 70 where name = "曹孟德";
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> -- 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
mysql> update exam_result set math = math+30 order by math+chinese+english limit 3;
Query OK, 2 rows affected (0.01 sec)
Rows matched: 3 Changed: 2 Warnings: 0
这里有几个点需要注意一下,
语法
DELETEFROM table_name [WHERE ...] [ORDERBY ...] [LIMIT ...]
示例
mysql> -- 删除孙悟空同学的考试成绩
mysql> delete from exam_result where name = "孙悟空";
Query OK, 1 row affected (0.01 sec)
mysql> -- 删除姓孙的同学的考试成绩
mysql> delete from exam_result where name like "孙%";
Query OK, 1 row affected (0.01 sec)
mysql> -- 删除数学第一名的同学的考试成绩
mysql>- delete from exam_result order by math desc limit 1;
mysql> -- 删除整张exam_result表
mysql> delete from exam_result ;
注意
delete from 表名
与 drop 表名
前者是表里面的内容删除,但是表还在,而后者是表整个都直接删除了。
创建表时,可以指定某列不为空:
示例
mysql> create table student (id int not null,name varchar(20),qq_email varchar(10));
Query OK, 0 rows affected (0.03 sec)
mysql> desc student;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| name | varchar(20) | YES | | NULL | |
| qq_email | varchar(10) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
在设置了该列的约束NOT NULL后,此行一旦插入id = null 就会报错。
插入数据或者修改数据的时候,就会先查询,先看看数据是否已经存在,如果不存在,就能够插入、修改成功,如果存在就插入或者修改失败。
示例:
mysql> create table student (id int unique,name varchar(10) not null);
Query OK, 0 rows affected (0.02 sec)
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | UNI | NULL | |
| name | varchar(10) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into student values(1,"zhangsan");
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
+------+----------+
1 row in set (0.00 sec)
mysql> insert into student values(1,"lisi");
ERROR 1062 (23000): Duplicate entry '1' for key 'id'
duplicate 重复的,entry 条目,入口
示例:
指定插入数据时,name列为空,默认值“无名氏”
mysql> drop table if exists student;
Query OK, 0 rows affected (0.01 sec)
mysql> create table student(id int unique,name varchar(20) default "无名氏");
Query OK, 0 rows affected (0.02 sec)
mysql> insert into student(id) values(1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+------+--------+
| id | name |
+------+--------+
| 1 | 无名氏 |
+------+--------+
1 row in set (0.00 sec)
mysql> drop table if exists student;
Query OK, 0 rows affected (0.01 sec)
mysql> create table student (id int primary key,name varchar(20) not null);
Query OK, 0 rows affected (0.02 sec)
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
示例
mysql> drop table if exists student;
Query OK, 0 rows affected (0.01 sec)
ysql> create table student (id int primary key auto_increment,name varchar(20));
Query OK, 0 rows affected (0.02 sec)
mysql> desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> insert into student(name) values("张三");
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 1 | 张三 |
+----+------+
1 row in set (0.00 sec)
mysql> insert into student(id,name) values(null,"李四");
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 1 | 张三 |
| 2 | 李四 |
+----+------+
2 rows in set (0.00 sec)
mysql> insert into student values(100,"王五");
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+-----+------+
| id | name |
+-----+------+
| 1 | 张三 |
| 2 | 李四 |
| 100 | 王五 |
+-----+------+
3 rows in set (0.00 sec)
mysql> select * from student;
+-----+------+
| id | name |
+-----+------+
| 1 | 张三 |
| 2 | 李四 |
| 100 | 王五 |
| 101 | 六六 |
+-----+------+
4 rows in set (0.00 sec)
语法:
foreign key (字段名) references 主表(列)
示例
mysql> create table class (classId int primary key auto_increment ,className varchar(20));
Query OK, 0 rows affected (0.02 sec)
mysql> drop table if exists student;
Query OK, 0 rows affected (0.01 sec)
mysql> create table student(studentId int primary key ,studentName varchar(20),classId int,
-> foreign key (classId) references class(classId));
Query OK, 0 rows affected (0.02 sec)
mysql> desc student;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| studentId | int(11) | NO | PRI | NULL | |
| studentName | varchar(20) | YES | | NULL | |
| classId | int(11) | YES | MUL | NULL | |
+-------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> desc class;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| classId | int(11) | NO | PRI | NULL | auto_increment |
| className | varchar(20) | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> insert into student values(123,"zhangsan",1);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`base1`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`classId`) REFERENCES `class` (`classId`))
其中Cannot add or update a child row: a foreign key constraint fails (
base1.
student, CONSTRAINT
student_ibfk_1 FOREIGN KEY (
classId) REFERENCES
class (
classId))
student中的classId受到class表里面的classId约束,在MySQL中我们将student表称之为子表,class表称之为父表。这句话翻译过来“不能增加或者修改一个子行:一个外键约束(constraint)失败”
mysql> insert into class values(null,"一班"),(null,"二班");
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from class;
+---------+-----------+
| classId | className |
+---------+-----------+
| 1 | 一班 |
| 2 | 二班 |
+---------+-----------+
2 rows in set (0.00 sec)
mysql> insert into student values(100,"张三",1),(101,"李四",2);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from student;
+-----------+-------------+---------+
| studentId | studentName | classId |
+-----------+-------------+---------+
| 100 | 张三 | 1 |
| 101 | 李四 | 2 |
+-----------+-------------+---------+
2 rows in set (0.00 sec)
不但插入会影响,修改也是会影响,如果修改的classId的值并不在class表中,那么就会报错。
mysql> select * from student;
+-----------+-------------+---------+
| studentId | studentName | classId |
+-----------+-------------+---------+
| 100 | 张三 | 1 |
| 101 | 李四 | 2 |
+-----------+-------------+-
mysql> update student set classId = 2 where studentId = 100;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from student;
+-----------+-------------+---------+
| studentId | studentName | classId |
+-----------+-------------+---------+
| 100 | 张三 | 2 |
| 101 | 李四 | 2 |
+-----------+-------------+---------+
2 rows in set (0.00 sec)
mysql> select * from student;
+-----------+-------------+---------+
| studentId | studentName | classId |
+-----------+-------------+---------+
| 1 | zhangsan | 1 |
| 2 | lisi | 2 |
+-----------+-------------+---------+
2 rows in set (0.00 sec)
mysql> delete from class where classId = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`base1`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`classId`) REFERENCES `class` (`classId`))
那么此时如果我此时确实是有删除这个班级记录的需求的呢?
比如说现在班级改制,将二班这个记录删除,但是这student表不变,作为存根。那么这样我们就在class表里面在增加一个列,标记为删除,实际上是逻辑删除了。
示例:
先定义一些表用于测试数据。
mysql> create table course(courseId int primary key,curseName varchar(20));
Query OK, 0 rows affected (0.02 sec)
mysql> create table student(studentId int primary key,studentName varchar(20));
Query OK, 0 rows affected (0.01 sec)
mysql> create table test(testId int primary key auto_increment,studentId int,courseId int,foreign key (studentId) references student(studentId),
foreign key (courseId) references course(courseId));
Query OK, 0 rows affected (0.03 sec)
mysql> desc student;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| studentId | int(11) | NO | PRI | NULL | |
| studentName | varchar(20) | YES | | NULL | |
+-------------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> desc course;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| courseId | int(11) | NO | PRI | NULL | |
| curseName | varchar(20) | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> desc test;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| testId | int(11) | NO | PRI | NULL | auto_increment |
| studentId | int(11) | YES | MUL | NULL | |
| courseId | int(11) | YES | MUL | NULL | |
+-----------+---------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
插入查询结果
INSERT INTO table_name [(column [, column ...])] SELECT ...
示例
创建一张用户表,设计有userId用户ID、name姓名、studentId学号、sex性别。需要把已有的学生数据复制进来,可以复制的字段为name,studentId字段
mysql> create table user(userId int primary key auto_increment,userName varchar(20),studentId int,sec varchar(10));
Query OK, 0 rows affected (0.02 sec)
mysql> desc user;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| userId | int(11) | NO | PRI | NULL | auto_increment |
| userName | varchar(20) | YES | | NULL | |
| studentId | int(11) | YES | | NULL | |
| sec | varchar(10) | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> insert into student values(1,"a"),(2,"b"),(3,"c");
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> insert into user(userName,studentId) select studentName,studentId from student;
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;
+-----------+-------------+
| studentId | studentName |
+-----------+-------------+
| 1 | a |
| 2 | b |
| 3 | c |
+-----------+-------------+
3 rows in set (0.00 sec)
mysql> select * from user;
+--------+----------+-----------+------+
| userId | userName | studentId | sec |
+--------+----------+-----------+------+
| 1 | a | 1 | NULL |
| 2 | b | 2 | NULL |
| 3 | c | 3 | NULL |
+--------+----------+-----------+------+
3 rows in set (0.00 sec)
常见的统计总数、计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有
示例:
mysql> select * from student;
+-----------+-------------+
| studentId | studentName |
+-----------+-------------+
| 1 | a |
| 2 | b |
| 3 | c |
+-----------+-------------+
3 rows in set (0.00 sec)
mysql> select count(*) from student;
+----------+
| count(*) |
+----------+
| 3 |
+----------+
1 row in set (0.00 sec)
mysql> insert into student values(4,"a");
Query OK, 1 row affected (0.00 sec)
DISTINCT
去重关键字,可以避免将相同记录计数。mysql> insert into student values(4,"a");
Query OK, 1 row affected (0.00 sec)
mysql> select count(name) from student;
ERROR 1054 (42S22): Unknown column 'name' in 'field list'
mysql> select count(studentName) from student;
+--------------------+
| count(studentName) |
+--------------------+
| 4 |
+--------------------+
1 row in set (0.00 sec)
mysql> select count( distinct studentName) from student;
+------------------------------+
| count( distinct studentName) |
+------------------------------+
| 3 |
+------------------------------+
1 row in set (0.00 sec)
mysql> insert into student(studentId) values(5);
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+-----------+-------------+
| studentId | studentName |
+-----------+-------------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | a |
| 5 | NULL |
+-----------+-------------+
5 rows in set (0.00 sec)
mysql> select count(studentName) from student;
+--------------------+
| count(studentName) |
+--------------------+
| 4 |
+--------------------+
1 row in set (0.00 sec)
示例
mysql> DROP TABLE IF EXISTS exam_result;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE exam_result (
-> id INT,
-> name VARCHAR(20),
-> chinese DECIMAL(3,1),
-> math DECIMAL(3,1),
-> english DECIMAL(3,1)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> -- 插入测试数据
mysql> INSERT INTO exam_result (id,name, chinese, math, english) VALUES
-> (1,'唐三藏', 67, 98, 56),
-> (2,'孙悟空', 87.5, 78, 77),
-> (3,'猪悟能', 88, 98.5, 90),
-> (4,'曹孟德', 82, 84, 67),
-> (5,'刘玄德', 55.5, 85, 45),
-> (6,'孙权', 70, 73, 78.5),
-> (7,'宋公明', 75, 65, 30);
Query OK, 7 rows affected (0.01 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> select * from exam_result;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
+------+--------+---------+------+---------+
7 rows in set (0.00 sec)
mysql> select sum(name) from exam_result;
+-----------+
| sum(name) |
+-----------+
| 0 |
+-----------+
1 row in set, 8 warnings (0.00 sec)
这里有8个warningsm,可以看一下warning
mysql> show warnings;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '唐三藏' |
| Warning | 1292 | Truncated incorrect DOUBLE value: '孙悟空' |
| Warning | 1292 | Truncated incorrect DOUBLE value: '猪悟能' |
| Warning | 1292 | Truncated incorrect DOUBLE value: '曹孟德' |
| Warning | 1292 | Truncated incorrect DOUBLE value: '刘玄德' |
| Warning | 1292 | Truncated incorrect DOUBLE value: '孙权' |
| Warning | 1292 | Truncated incorrect DOUBLE value: '宋公明' |
| Warning | 1292 | Truncated incorrect DOUBLE value: '贾宝玉' |
+---------+------+--------------------------------------------+
8 rows in set (0.00 sec)
mysql> select sum(chinese) from exam_result;
+--------------+
| sum(chinese) |
+--------------+
| 525.0 |
+--------------+
1 row in set (0.00 sec)
mysql> insert into exam_result values(null,"贾宝玉",null,null,52.1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from exam_result;
+------+--------+---------+------+---------+
| id | name | chinese | math | english |
+------+--------+---------+------+---------+
| 1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
| 2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
| 3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
| 4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
| 5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
| 6 | 孙权 | 70.0 | 73.0 | 78.5 |
| 7 | 宋公明 | 75.0 | 65.0 | 30.0 |
| NULL | 贾宝玉 | NULL | NULL | 52.1 |
+------+--------+---------+------+---------+
8 rows in set (0.00 sec)
mysql> select sum(chinese) from exam_result;
+--------------+
| sum(chinese) |
+--------------+
| 525.0 |
+--------------+
1 row in set (0.00 sec)
示例:
返回 > 70 分以上的数学最低分
mysql> select min(math) from exam_result where math>70;
+-----------+
| min(math) |
+-----------+
| 73.0 |
+-----------+
1 row in set (0.00 sec)
SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用 GROUP BY 进行分组查询时,SELECT 指定的字段必须是“分组依据字段”,其他字段若想出现在SELECT 中则必须包含在聚合函数中。
语法
select column1, sum(column2), .. from table group by column1,column3;
示例:
准备测试表及数据:职员表,有employerId(主键)、name(姓名)、role(角色)、salary(薪水)
mysql> create table emp(
-> id int primary key auto_increment,
-> name varchar(20) not null,
-> role varchar(20) not null,
-> salary numeric(11,2)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> insert into emp(name, role, salary) values
-> ('马云','服务员', 1000.20),
-> ('马化腾','游戏陪玩', 2000.99),
-> ('孙悟空','游戏角色', 999.11),
-> ('猪无能','游戏角色', 333.5),
-> ('沙和尚','游戏角色', 700.33),
-> ('隔壁老王','董事长', 12000.66);
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from emp;
+----+----------+----------+----------+
| id | name | role | salary |
+----+----------+----------+----------+
| 1 | 马云 | 服务员 | 1000.20 |
| 2 | 马化腾 | 游戏陪玩 | 2000.99 |
| 3 | 孙悟空 | 游戏角色 | 999.11 |
| 4 | 猪无能 | 游戏角色 | 333.50 |
| 5 | 沙和尚 | 游戏角色 | 700.33 |
| 6 | 隔壁老王 | 董事长 | 12000.66 |
+----+----------+----------+----------+
6 rows in set (0.00 sec)
查询每个角色的最高工资、最低工资和平均工资
mysql> select role,min(salary) as "最低工资",max(salary) as "最高工资",avg(salary) as "平均工资" from emp group by role;
+----------+----------+----------+--------------+
| role | 最低工资 | 最高工资 | 平均工资 |
+----------+----------+----------+--------------+
| 服务员 | 1000.20 | 1000.20 | 1000.200000 |
| 游戏角色 | 333.50 | 999.11 | 677.646667 |
| 游戏陪玩 | 2000.99 | 2000.99 | 2000.990000 |
| 董事长 | 12000.66 | 12000.66 | 12000.660000 |
+----------+----------+----------+--------------+
4 rows in set (0.00 sec)
mysql> select name,min(salary) as "最低工资",max(salary) as "最高工资",avg(salary) as "平均工资" from emp group by role;
+----------+----------+----------+--------------+
| name | 最低工资 | 最高工资 | 平均工资 |
+----------+----------+----------+--------------+
| 马云 | 1000.20 | 1000.20 | 1000.200000 |
| 孙悟空 | 333.50 | 999.11 | 677.646667 |
| 马化腾 | 2000.99 | 2000.99 | 2000.990000 |
| 隔壁老王 | 12000.66 | 12000.66 | 12000.660000 |
+----------+----------+----------+--------------+
4 rows in set (0.00 sec)
最后name作为select 查询是没哟意义的。只有role才有意义。
示例:
求去除孙悟空同学后的每个岗位的平均薪资。
mysql> select role,avg(salary) from emp where name != "孙悟空" group by role;
+----------+--------------+
| role | avg(salary) |
+----------+--------------+
| 服务员 | 1000.200000 |
| 游戏角色 | 516.915000 |
| 游戏陪玩 | 2000.990000 |
| 董事长 | 12000.660000 |
+----------+--------------+
4 rows in set (0.00 sec)
where在group by 之前执行,先筛选出name中没有孙悟空的所有记录,再将这些记录分组,再去求这些记录的平均薪资。
GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用 HAVING
示例
mysql> select role,avg(salary) from emp group by role having name != "孙悟空";
ERROR 1054 (42S22): Unknown column 'name' in 'having clause'
mysql> select role,avg(salary) from emp group by role having role != "董事长";
+----------+-------------+
| role | avg(salary) |
+----------+-------------+
| 服务员 | 1000.200000 |
| 游戏角色 | 677.646667 |
| 游戏陪玩 | 2000.990000 |
+----------+-------------+
3 rows in set (0.00 sec)
注意:此时的having筛选对象一定是分组后的表里面有的列(属性),比如在上述中,name就不在分完组后的表中,所以会报错。
显示平均工资低于1500的角色和它的平均工资
mysql> select role,max(salary),min(salary),avg(salary) from emp group by role
-> having avg(salary)<1500;
+----------+-------------+-------------+-------------+
| role | max(salary) | min(salary) | avg(salary) |
+----------+-------------+-------------+-------------+
| 服务员 | 1000.20 | 1000.20 | 1000.200000 |
| 游戏角色 | 999.11 | 333.50 | 677.646667 |
+----------+-------------+-------------+-------------+
2 rows in set (0.00 sec)
去除孙悟空同学后分组,求每个角色的平均薪资,并去除老板这一角色进行查询
mysql> select role,avg(salary) from emp where name != "孙悟空" group by role having role != "董事长";
+----------+-------------+
| role | avg(salary) |
+----------+-------------+
| 服务员 | 1000.200000 |
| 游戏角色 | 516.915000 |
| 游戏陪玩 | 2000.990000 |
+----------+-------------+
3 rows in set (0.00 sec)
实际上 where 和having 可以理解为一个执行在聚合函数之前,一个执行在聚合函数之后
mysql> select role,avg(salary) from emp where name != "孙悟空" having role != "董事长";
+--------+-------------+
| role | avg(salary) |
+--------+-------------+
| 服务员 | 3207.136000 |
+--------+-------------+
1 row in set (0.00 sec)
mysql> select role,avg(salary) from emp where name != "孙悟空" ;
+--------+-------------+
| role | avg(salary) |
+--------+-------------+
| 服务员 | 3207.136000 |
+--------+-------------+
1 row in set (0.00 sec)
mysql> select role,avg(salary) from emp where name != "孙悟空" having role != "服务员";
Empty set (0.00 sec)
mysql> select role from emp where name != "孙悟空" having role != "服务员";
+----------+
| role |
+----------+
| 游戏陪玩 |
| 游戏角色 |
| 游戏角色 |
| 董事长 |
+----------+
4 rows in set (0.00 sec)
实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积。
示例:
建立三个表,班级表calsses、学生表student、课程表course
mysql> -- 创建班级表,有使用MySQL关键字作为字段时,需要使用``来标识
mysql> DROP TABLE IF EXISTS classes;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE TABLE classes (
-> id INT PRIMARY KEY auto_increment,
-> name VARCHAR(20),
-> `desc` VARCHAR(100)
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> DROP TABLE IF EXISTS student;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE TABLE student (
-> id INT PRIMARY KEY auto_increment,
-> sn INT UNIQUE,
-> name VARCHAR(20) DEFAULT 'unkown',
-> qq_mail VARCHAR(20),
-> classes_id int,
-> FOREIGN KEY (classes_id) REFERENCES classes(id)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> -- 创建课程表
mysql> DROP TABLE IF EXISTS course;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE TABLE course (
-> id INT PRIMARY KEY auto_increment,
-> name VARCHAR(20)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> CREATE TABLE score (
-> id INT PRIMARY KEY auto_increment,
-> score DECIMAL(3, 1),
-> student_id int,
-> course_id int,
-> FOREIGN KEY (student_id) REFERENCES student(id),
-> FOREIGN KEY (course_id) REFERENCES course(id)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> desc classes;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| desc | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> desc student;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| sn | int(11) | YES | UNI | NULL | |
| name | varchar(20) | YES | | unkown | |
| qq_mail | varchar(20) | YES | | NULL | |
| classes_id | int(11) | YES | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> desc course;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> desc score;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| score | decimal(3,1) | YES | | NULL | |
| student_id | int(11) | YES | MUL | NULL | |
| course_id | int(11) | YES | MUL | NULL | |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
插入数据为测试做准备
mysql> insert into classes(name, `desc`) values
-> ('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
-> ('中文系2019级3班','学习了中国传统文学'),
-> ('自动化2019级5班','学习了机械自动化');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> insert into student(sn, name, qq_mail, classes_id) values
-> ('09982','黑旋风李逵','[email protected]',1),
-> ('00835','菩提老祖',null,1),
-> ('00391','白素贞',null,1),
-> ('00031','许仙','[email protected]',1),
-> ('00054','不想毕业',null,1),
-> ('51234','好好说话','[email protected]',2),
-> ('83223','tellme',null,2),
-> ('09527','老外学中文','[email protected]',2);
Query OK, 8 rows affected (0.01 sec)
Records: 8 Duplicates: 0 Warnings: 0
mysql> insert into course(name) values
-> ('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> DROP TABLE IF EXISTS score;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE TABLE score (
-> id INT PRIMARY KEY auto_increment,
-> score DECIMAL(3, 1),
-> student_id int,
-> course_id int,
-> FOREIGN KEY (student_id) REFERENCES student(id),
-> FOREIGN KEY (course_id) REFERENCES course(id)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> desc score;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| score | decimal(3,1) | YES | | NULL | |
| student_id | int(11) | YES | MUL | NULL | |
| course_id | int(11) | YES | MUL | NULL | |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> insert into course(name) values
-> ('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> insert into score(score, student_id, course_id) values
-> -- 黑旋风李逵
-> (70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-> -- 菩提老祖
-> (60, 2, 1),(59.5, 2, 5),
-> -- 白素贞
-> (33, 3, 1),(68, 3, 3),(99, 3, 5),
-> -- 许仙
-> (67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
-> -- 不想毕业
-> (81, 5, 1),(37, 5, 5),
-> -- 好好说话
-> (56, 6, 2),(43, 6, 4),(79, 6, 6),
-> -- tellme
-> (80, 7, 2),(92, 7, 6);
Query OK, 20 rows affected (0.01 sec)
Records: 20 Duplicates: 0 Warnings: 0
mysql> select * from classes;
+----+-------------------+-----------------------------------------------+
| id | name | desc |
+----+-------------------+-----------------------------------------------+
| 1 | 计算机系2019级1班 | 学习了计算机原理、C和Java语言、数据结构和算法 |
| 2 | 中文系2019级3班 | 学习了中国传统文学 |
| 3 | 自动化2019级5班 | 学习了机械自动化 |
+----+-------------------+-----------------------------------------------+
3 rows in set (0.00 sec)
mysql> select * from student;
+----+-------+------------+------------------+------------+
| id | sn | name | qq_mail | classes_id |
+----+-------+------------+------------------+------------+
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 |
| 3 | 391 | 白素贞 | NULL | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 |
| 7 | 83223 | tellme | NULL | 2 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 |
+----+-------+------------+------------------+------------+
8 rows in set (0.00 sec)
mysql> select * from course;
+----+--------------+
| id | name |
+----+--------------+
| 1 | Java |
| 2 | 中国传统文化 |
| 3 | 计算机原理 |
| 4 | 语文 |
| 5 | 高阶数学 |
| 6 | 英文 |
| 7 | Java |
| 8 | 中国传统文化 |
| 9 | 计算机原理 |
| 10 | 语文 |
| 11 | 高阶数学 |
| 12 | 英文 |
+----+--------------+
12 rows in set (0.00 sec)
mysql> select * from score;
+----+-------+------------+-----------+
| id | score | student_id | course_id |
+----+-------+------------+-----------+
| 1 | 70.5 | 1 | 1 |
| 2 | 98.5 | 1 | 3 |
| 3 | 33.0 | 1 | 5 |
| 4 | 98.0 | 1 | 6 |
| 5 | 60.0 | 2 | 1 |
| 6 | 59.5 | 2 | 5 |
| 7 | 33.0 | 3 | 1 |
| 8 | 68.0 | 3 | 3 |
| 9 | 99.0 | 3 | 5 |
| 10 | 67.0 | 4 | 1 |
| 11 | 23.0 | 4 | 3 |
| 12 | 56.0 | 4 | 5 |
| 13 | 72.0 | 4 | 6 |
| 14 | 81.0 | 5 | 1 |
| 15 | 37.0 | 5 | 5 |
| 16 | 56.0 | 6 | 2 |
| 17 | 43.0 | 6 | 4 |
| 18 | 79.0 | 6 | 6 |
| 19 | 80.0 | 7 | 2 |
| 20 | 92.0 | 7 | 6 |
+----+-------+------------+-----------+
20 rows in set (0.00 sec)
示例:
查询许仙同学的成绩
在查询之前先对score表和student表笛卡尔积
即 select * from score,student;
mysql> select * from student,score;
+----+-------+------------+------------------+------------+----+-------+------------+-----------+
| id | sn | name | qq_mail | classes_id | id | score | student_id | course_id |
+----+-------+------------+------------------+------------+----+-------+------------+-----------+
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 1 | 70.5 | 1 | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 1 | 70.5 | 1 | 1 |
| 3 | 391 | 白素贞 | NULL | 1 | 1 | 70.5 | 1 | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 1 | 70.5 | 1 | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 | 1 | 70.5 | 1 | 1 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 1 | 70.5 | 1 | 1 |
| 7 | 83223 | tellme | NULL | 2 | 1 | 70.5 | 1 | 1 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 1 | 70.5 | 1 | 1 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 2 | 98.5 | 1 | 3 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 2 | 98.5 | 1 | 3 |
| 3 | 391 | 白素贞 | NULL | 1 | 2 | 98.5 | 1 | 3 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 2 | 98.5 | 1 | 3 |
| 5 | 54 | 不想毕业 | NULL | 1 | 2 | 98.5 | 1 | 3 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 2 | 98.5 | 1 | 3 |
| 7 | 83223 | tellme | NULL | 2 | 2 | 98.5 | 1 | 3 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 2 | 98.5 | 1 | 3 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 3 | 33.0 | 1 | 5 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 3 | 33.0 | 1 | 5 |
| 3 | 391 | 白素贞 | NULL | 1 | 3 | 33.0 | 1 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 3 | 33.0 | 1 | 5 |
| 5 | 54 | 不想毕业 | NULL | 1 | 3 | 33.0 | 1 | 5 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 3 | 33.0 | 1 | 5 |
| 7 | 83223 | tellme | NULL | 2 | 3 | 33.0 | 1 | 5 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 3 | 33.0 | 1 | 5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 4 | 98.0 | 1 | 6 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 4 | 98.0 | 1 | 6 |
| 3 | 391 | 白素贞 | NULL | 1 | 4 | 98.0 | 1 | 6 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 4 | 98.0 | 1 | 6 |
| 5 | 54 | 不想毕业 | NULL | 1 | 4 | 98.0 | 1 | 6 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 4 | 98.0 | 1 | 6 |
| 7 | 83223 | tellme | NULL | 2 | 4 | 98.0 | 1 | 6 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 4 | 98.0 | 1 | 6 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 5 | 60.0 | 2 | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 5 | 60.0 | 2 | 1 |
| 3 | 391 | 白素贞 | NULL | 1 | 5 | 60.0 | 2 | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 5 | 60.0 | 2 | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 | 5 | 60.0 | 2 | 1 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 5 | 60.0 | 2 | 1 |
| 7 | 83223 | tellme | NULL | 2 | 5 | 60.0 | 2 | 1 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 5 | 60.0 | 2 | 1 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 6 | 59.5 | 2 | 5 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 6 | 59.5 | 2 | 5 |
| 3 | 391 | 白素贞 | NULL | 1 | 6 | 59.5 | 2 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 6 | 59.5 | 2 | 5 |
| 5 | 54 | 不想毕业 | NULL | 1 | 6 | 59.5 | 2 | 5 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 6 | 59.5 | 2 | 5 |
| 7 | 83223 | tellme | NULL | 2 | 6 | 59.5 | 2 | 5 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 6 | 59.5 | 2 | 5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 7 | 33.0 | 3 | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 7 | 33.0 | 3 | 1 |
| 3 | 391 | 白素贞 | NULL | 1 | 7 | 33.0 | 3 | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 7 | 33.0 | 3 | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 | 7 | 33.0 | 3 | 1 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 7 | 33.0 | 3 | 1 |
| 7 | 83223 | tellme | NULL | 2 | 7 | 33.0 | 3 | 1 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 7 | 33.0 | 3 | 1 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 8 | 68.0 | 3 | 3 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 8 | 68.0 | 3 | 3 |
| 3 | 391 | 白素贞 | NULL | 1 | 8 | 68.0 | 3 | 3 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 8 | 68.0 | 3 | 3 |
| 5 | 54 | 不想毕业 | NULL | 1 | 8 | 68.0 | 3 | 3 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 8 | 68.0 | 3 | 3 |
| 7 | 83223 | tellme | NULL | 2 | 8 | 68.0 | 3 | 3 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 8 | 68.0 | 3 | 3 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 9 | 99.0 | 3 | 5 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 9 | 99.0 | 3 | 5 |
| 3 | 391 | 白素贞 | NULL | 1 | 9 | 99.0 | 3 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 9 | 99.0 | 3 | 5 |
| 5 | 54 | 不想毕业 | NULL | 1 | 9 | 99.0 | 3 | 5 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 9 | 99.0 | 3 | 5 |
| 7 | 83223 | tellme | NULL | 2 | 9 | 99.0 | 3 | 5 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 9 | 99.0 | 3 | 5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 10 | 67.0 | 4 | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 10 | 67.0 | 4 | 1 |
| 3 | 391 | 白素贞 | NULL | 1 | 10 | 67.0 | 4 | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 10 | 67.0 | 4 | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 | 10 | 67.0 | 4 | 1 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 10 | 67.0 | 4 | 1 |
| 7 | 83223 | tellme | NULL | 2 | 10 | 67.0 | 4 | 1 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 10 | 67.0 | 4 | 1 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 11 | 23.0 | 4 | 3 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 11 | 23.0 | 4 | 3 |
| 3 | 391 | 白素贞 | NULL | 1 | 11 | 23.0 | 4 | 3 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 11 | 23.0 | 4 | 3 |
| 5 | 54 | 不想毕业 | NULL | 1 | 11 | 23.0 | 4 | 3 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 11 | 23.0 | 4 | 3 |
| 7 | 83223 | tellme | NULL | 2 | 11 | 23.0 | 4 | 3 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 11 | 23.0 | 4 | 3 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 12 | 56.0 | 4 | 5 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 12 | 56.0 | 4 | 5 |
| 3 | 391 | 白素贞 | NULL | 1 | 12 | 56.0 | 4 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 12 | 56.0 | 4 | 5 |
| 5 | 54 | 不想毕业 | NULL | 1 | 12 | 56.0 | 4 | 5 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 12 | 56.0 | 4 | 5 |
| 7 | 83223 | tellme | NULL | 2 | 12 | 56.0 | 4 | 5 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 12 | 56.0 | 4 | 5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 13 | 72.0 | 4 | 6 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 13 | 72.0 | 4 | 6 |
| 3 | 391 | 白素贞 | NULL | 1 | 13 | 72.0 | 4 | 6 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 13 | 72.0 | 4 | 6 |
| 5 | 54 | 不想毕业 | NULL | 1 | 13 | 72.0 | 4 | 6 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 13 | 72.0 | 4 | 6 |
| 7 | 83223 | tellme | NULL | 2 | 13 | 72.0 | 4 | 6 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 13 | 72.0 | 4 | 6 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 14 | 81.0 | 5 | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 14 | 81.0 | 5 | 1 |
| 3 | 391 | 白素贞 | NULL | 1 | 14 | 81.0 | 5 | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 14 | 81.0 | 5 | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 | 14 | 81.0 | 5 | 1 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 14 | 81.0 | 5 | 1 |
| 7 | 83223 | tellme | NULL | 2 | 14 | 81.0 | 5 | 1 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 14 | 81.0 | 5 | 1 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 15 | 37.0 | 5 | 5 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 15 | 37.0 | 5 | 5 |
| 3 | 391 | 白素贞 | NULL | 1 | 15 | 37.0 | 5 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 15 | 37.0 | 5 | 5 |
| 5 | 54 | 不想毕业 | NULL | 1 | 15 | 37.0 | 5 | 5 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 15 | 37.0 | 5 | 5 |
| 7 | 83223 | tellme | NULL | 2 | 15 | 37.0 | 5 | 5 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 15 | 37.0 | 5 | 5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 16 | 56.0 | 6 | 2 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 16 | 56.0 | 6 | 2 |
| 3 | 391 | 白素贞 | NULL | 1 | 16 | 56.0 | 6 | 2 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 16 | 56.0 | 6 | 2 |
| 5 | 54 | 不想毕业 | NULL | 1 | 16 | 56.0 | 6 | 2 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 16 | 56.0 | 6 | 2 |
| 7 | 83223 | tellme | NULL | 2 | 16 | 56.0 | 6 | 2 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 16 | 56.0 | 6 | 2 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 17 | 43.0 | 6 | 4 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 17 | 43.0 | 6 | 4 |
| 3 | 391 | 白素贞 | NULL | 1 | 17 | 43.0 | 6 | 4 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 17 | 43.0 | 6 | 4 |
| 5 | 54 | 不想毕业 | NULL | 1 | 17 | 43.0 | 6 | 4 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 17 | 43.0 | 6 | 4 |
| 7 | 83223 | tellme | NULL | 2 | 17 | 43.0 | 6 | 4 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 17 | 43.0 | 6 | 4 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 18 | 79.0 | 6 | 6 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 18 | 79.0 | 6 | 6 |
| 3 | 391 | 白素贞 | NULL | 1 | 18 | 79.0 | 6 | 6 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 18 | 79.0 | 6 | 6 |
| 5 | 54 | 不想毕业 | NULL | 1 | 18 | 79.0 | 6 | 6 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 18 | 79.0 | 6 | 6 |
| 7 | 83223 | tellme | NULL | 2 | 18 | 79.0 | 6 | 6 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 18 | 79.0 | 6 | 6 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 19 | 80.0 | 7 | 2 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 19 | 80.0 | 7 | 2 |
| 3 | 391 | 白素贞 | NULL | 1 | 19 | 80.0 | 7 | 2 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 19 | 80.0 | 7 | 2 |
| 5 | 54 | 不想毕业 | NULL | 1 | 19 | 80.0 | 7 | 2 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 19 | 80.0 | 7 | 2 |
| 7 | 83223 | tellme | NULL | 2 | 19 | 80.0 | 7 | 2 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 19 | 80.0 | 7 | 2 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 20 | 92.0 | 7 | 6 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 20 | 92.0 | 7 | 6 |
| 3 | 391 | 白素贞 | NULL | 1 | 20 | 92.0 | 7 | 6 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 20 | 92.0 | 7 | 6 |
| 5 | 54 | 不想毕业 | NULL | 1 | 20 | 92.0 | 7 | 6 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 20 | 92.0 | 7 | 6 |
| 7 | 83223 | tellme | NULL | 2 | 20 | 92.0 | 7 | 6 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | 20 | 92.0 | 7 | 6 |
+----+-------+------------+------------------+------------+----+-------+------------+-----------+
160 rows in set (0.00 sec)
但是这里面有很多的无效数据,我们需要将无效数据剔除,一般是添加两个表的外键相等。
通过“表名.列名”来访问每个表的某个列
mysql> select * from student,score where student.id = score.student_id;
+----+-------+------------+-----------------+------------+----+-------+------------+-----------+
| id | sn | name | qq_mail | classes_id | id | score | student_id | course_id |
+----+-------+------------+-----------------+------------+----+-------+------------+-----------+
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 1 | 70.5 | 1 | 1 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 2 | 98.5 | 1 | 3 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 3 | 33.0 | 1 | 5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 4 | 98.0 | 1 | 6 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 5 | 60.0 | 2 | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 6 | 59.5 | 2 | 5 |
| 3 | 391 | 白素贞 | NULL | 1 | 7 | 33.0 | 3 | 1 |
| 3 | 391 | 白素贞 | NULL | 1 | 8 | 68.0 | 3 | 3 |
| 3 | 391 | 白素贞 | NULL | 1 | 9 | 99.0 | 3 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 10 | 67.0 | 4 | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 11 | 23.0 | 4 | 3 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 12 | 56.0 | 4 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 13 | 72.0 | 4 | 6 |
| 5 | 54 | 不想毕业 | NULL | 1 | 14 | 81.0 | 5 | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 | 15 | 37.0 | 5 | 5 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 16 | 56.0 | 6 | 2 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 17 | 43.0 | 6 | 4 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 18 | 79.0 | 6 | 6 |
| 7 | 83223 | tellme | NULL | 2 | 19 | 80.0 | 7 | 2 |
| 7 | 83223 | tellme | NULL | 2 | 20 | 92.0 | 7 | 6 |
+----+-------+------------+-----------------+------------+----+-------+------------+-----------+
20 rows in set (0.01 sec)
最后查询许仙同学的成绩
mysql> select student.name,score.score from student,score where student.id = score.student_id and student.name = "许仙";
+------+-------+
| name | score |
+------+-------+
| 许仙 | 67.0 |
| 许仙 | 23.0 |
| 许仙 | 56.0 |
| 许仙 | 72.0 |
+------+-------+
4 rows in set (0.00 sec)
此外我们也可以通过join来实现笛卡尔积,此时后续条件也不是使用where关键字,而是 on
示例
mysql> select student.name,score.score from student join score on student.id = score.student_id and student.name = "许仙";
+------+-------+
| name | score |
+------+-------+
| 许仙 | 67.0 |
| 许仙 | 23.0 |
| 许仙 | 56.0 |
| 许仙 | 72.0 |
+------+-------+
4 rows in set (0.00 sec)
查询所有同学的总成绩,及同学的个人信息。
mysql> select student.*,score.score from student,score where student.id = score.student_id;
+----+-------+------------+-----------------+------------+-------+
| id | sn | name | qq_mail | classes_id | score |
+----+-------+------------+-----------------+------------+-------+
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 70.5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 98.5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 33.0 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 98.0 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 60.0 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 59.5 |
| 3 | 391 | 白素贞 | NULL | 1 | 33.0 |
| 3 | 391 | 白素贞 | NULL | 1 | 68.0 |
| 3 | 391 | 白素贞 | NULL | 1 | 99.0 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 67.0 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 23.0 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 56.0 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 72.0 |
| 5 | 54 | 不想毕业 | NULL | 1 | 81.0 |
| 5 | 54 | 不想毕业 | NULL | 1 | 37.0 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 56.0 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 43.0 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 79.0 |
| 7 | 83223 | tellme | NULL | 2 | 80.0 |
| 7 | 83223 | tellme | NULL | 2 | 92.0 |
+----+-------+------------+-----------------+------------+-------+
20 rows in set (0.00 sec)
注意上述查询的是每个同学对应课程的对应分数。而不是总分,那么要查询总分还需要进行分组结合聚合函数
去筛选出最后的总分数。
mysql> select student.id,student.name,sum(score.score) from student,score where student.id = score.student_id group by student.id;
+----+------------+------------------+
| id | name | sum(score.score) |
+----+------------+------------------+
| 1 | 黑旋风李逵 | 300.0 |
| 2 | 菩提老祖 | 119.5 |
| 3 | 白素贞 | 200.0 |
| 4 | 许仙 | 218.0 |
| 5 | 不想毕业 | 118.0 |
| 6 | 好好说话 | 178.0 |
| 7 | tellme | 172.0 |
+----+------------+------------------+
7 rows in set (0.00 sec)
三个表也可以连接,显示学生所有课程的成绩
mysql> select * from student,course,score where student.id = score.student_id and course.id = score.course_id;
+----+-------+------------+-----------------+------------+----+--------------+----+-------+------------+-----------+
| id | sn | name | qq_mail | classes_id | id | name | id | score | student_id | course_id |
+----+-------+------------+-----------------+------------+----+--------------+----+-------+------------+-----------+
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 1 | Java | 1 | 70.5 | 1 | 1 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 3 | 计算机原理 | 2 | 98.5 | 1 | 3 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 5 | 高阶数学 | 3 | 33.0 | 1 | 5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 6 | 英文 | 4 | 98.0 | 1 | 6 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 1 | Java | 5 | 60.0 | 2 | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 5 | 高阶数学 | 6 | 59.5 | 2 | 5 |
| 3 | 391 | 白素贞 | NULL | 1 | 1 | Java | 7 | 33.0 | 3 | 1 |
| 3 | 391 | 白素贞 | NULL | 1 | 3 | 计算机原理 | 8 | 68.0 | 3 | 3 |
| 3 | 391 | 白素贞 | NULL | 1 | 5 | 高阶数学 | 9 | 99.0 | 3 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 1 | Java | 10 | 67.0 | 4 | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 3 | 计算机原理 | 11 | 23.0 | 4 | 3 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 5 | 高阶数学 | 12 | 56.0 | 4 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 6 | 英文 | 13 | 72.0 | 4 | 6 |
| 5 | 54 | 不想毕业 | NULL | 1 | 1 | Java | 14 | 81.0 | 5 | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 | 5 | 高阶数学 | 15 | 37.0 | 5 | 5 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 2 | 中国传统文化 | 16 | 56.0 | 6 | 2 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 4 | 语文 | 17 | 43.0 | 6 | 4 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 6 | 英文 | 18 | 79.0 | 6 | 6 |
| 7 | 83223 | tellme | NULL | 2 | 2 | 中国传统文化 | 19 | 80.0 | 7 | 2 |
| 7 | 83223 | tellme | NULL | 2 | 6 | 英文 | 20 | 92.0 | 7 | 6 |
+----+-------+------------+-----------------+------------+----+--------------+----+-------+------------+-----------+
20 rows in set (0.01 sec)
mysql> select student.name,course.name,score.score from student,course,score where student.id = score.student_id and course.id = score.course_id;
+------------+--------------+-------+
| name | name | score |
+------------+--------------+-------+
| 黑旋风李逵 | Java | 70.5 |
| 黑旋风李逵 | 计算机原理 | 98.5 |
| 黑旋风李逵 | 高阶数学 | 33.0 |
| 黑旋风李逵 | 英文 | 98.0 |
| 菩提老祖 | Java | 60.0 |
| 菩提老祖 | 高阶数学 | 59.5 |
| 白素贞 | Java | 33.0 |
| 白素贞 | 计算机原理 | 68.0 |
| 白素贞 | 高阶数学 | 99.0 |
| 许仙 | Java | 67.0 |
| 许仙 | 计算机原理 | 23.0 |
| 许仙 | 高阶数学 | 56.0 |
| 许仙 | 英文 | 72.0 |
| 不想毕业 | Java | 81.0 |
| 不想毕业 | 高阶数学 | 37.0 |
| 好好说话 | 中国传统文化 | 56.0 |
| 好好说话 | 语文 | 43.0 |
| 好好说话 | 英文 | 79.0 |
| tellme | 中国传统文化 | 80.0 |
| tellme | 英文 | 92.0 |
+------------+--------------+-------+
20 rows in set (0.00 sec)
外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完
全显示我们就说是右外连接。
内连接与外连接大体是相同的,但是如果两个表的数据并不是一一对应的,此时进行内连接。结果只会显示两个表里面都有体现的数据。
如果进行左外连接。就是以左侧表为准,左侧表的数据都能体现出来。如果是右链接,就是以右侧表为准,右侧表数据都能体现出来。
-- 左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;
示例:
mysql> -- "老外学中文"同学 没有考试成绩(course—id和studentid都是空的),也显示出来了
mysql> select * from student stu left join score sco on stu.id=sco.student_id;
+----+-------+------------+------------------+------------+------+-------+------------+-----------+
| id | sn | name | qq_mail | classes_id | id | score | student_id | course_id |
+----+-------+------------+------------------+------------+------+-------+------------+-----------+
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 1 | 70.5 | 1 | 1 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 2 | 98.5 | 1 | 3 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 3 | 33.0 | 1 | 5 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 | 4 | 98.0 | 1 | 6 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 5 | 60.0 | 2 | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 | 6 | 59.5 | 2 | 5 |
| 3 | 391 | 白素贞 | NULL | 1 | 7 | 33.0 | 3 | 1 |
| 3 | 391 | 白素贞 | NULL | 1 | 8 | 68.0 | 3 | 3 |
| 3 | 391 | 白素贞 | NULL | 1 | 9 | 99.0 | 3 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 10 | 67.0 | 4 | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 11 | 23.0 | 4 | 3 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 12 | 56.0 | 4 | 5 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 | 13 | 72.0 | 4 | 6 |
| 5 | 54 | 不想毕业 | NULL | 1 | 14 | 81.0 | 5 | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 | 15 | 37.0 | 5 | 5 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 16 | 56.0 | 6 | 2 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 17 | 43.0 | 6 | 4 |
| 6 | 51234 | 好好说话 | say@qq.com | 2 | 18 | 79.0 | 6 | 6 |
| 7 | 83223 | tellme | NULL | 2 | 19 | 80.0 | 7 | 2 |
| 7 | 83223 | tellme | NULL | 2 | 20 | 92.0 | 7 | 6 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 | NULL | NULL | NULL | NULL |
+----+-------+------------+------------------+------------+------+-------+------------+-----------+
21 rows in set (0.00 sec)
mysql> -- 对应的右外连接为:
mysql> select * from score sco right join student stu on stu.id=sco.student_id;
+------+-------+------------+-----------+----+-------+------------+------------------+------------+
| id | score | student_id | course_id | id | sn | name | qq_mail | classes_id |
+------+-------+------------+-----------+----+-------+------------+------------------+------------+
| 1 | 70.5 | 1 | 1 | 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 |
| 2 | 98.5 | 1 | 3 | 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 |
| 3 | 33.0 | 1 | 5 | 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 |
| 4 | 98.0 | 1 | 6 | 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 |
| 5 | 60.0 | 2 | 1 | 2 | 835 | 菩提老祖 | NULL | 1 |
| 6 | 59.5 | 2 | 5 | 2 | 835 | 菩提老祖 | NULL | 1 |
| 7 | 33.0 | 3 | 1 | 3 | 391 | 白素贞 | NULL | 1 |
| 8 | 68.0 | 3 | 3 | 3 | 391 | 白素贞 | NULL | 1 |
| 9 | 99.0 | 3 | 5 | 3 | 391 | 白素贞 | NULL | 1 |
| 10 | 67.0 | 4 | 1 | 4 | 31 | 许仙 | xuxian@qq.com | 1 |
| 11 | 23.0 | 4 | 3 | 4 | 31 | 许仙 | xuxian@qq.com | 1 |
| 12 | 56.0 | 4 | 5 | 4 | 31 | 许仙 | xuxian@qq.com | 1 |
| 13 | 72.0 | 4 | 6 | 4 | 31 | 许仙 | xuxian@qq.com | 1 |
| 14 | 81.0 | 5 | 1 | 5 | 54 | 不想毕业 | NULL | 1 |
| 15 | 37.0 | 5 | 5 | 5 | 54 | 不想毕业 | NULL | 1 |
| 16 | 56.0 | 6 | 2 | 6 | 51234 | 好好说话 | say@qq.com | 2 |
| 17 | 43.0 | 6 | 4 | 6 | 51234 | 好好说话 | say@qq.com | 2 |
| 18 | 79.0 | 6 | 6 | 6 | 51234 | 好好说话 | say@qq.com | 2 |
| 19 | 80.0 | 7 | 2 | 7 | 83223 | tellme | NULL | 2 |
| 20 | 92.0 | 7 | 6 | 7 | 83223 | tellme | NULL | 2 |
| NULL | NULL | NULL | NULL | 8 | 9527 | 老外学中文 | foreigner@qq.com | 2 |
+------+-------+------------+-----------+----+-------+------------+------------------+------------+
21 rows in set (0.00 sec)
语法:
select 列名1,列名2.... from 表名1,表名2,表名3 where 条件1 and 条件2;
select 列名1,列名2.... from 表名1 join 表名2 on 条件1 join 表名3 on 条件2
示例:
mysql> -- 学生表、成绩表、课程表3张表关联查询
mysql> SELECT
-> stu.id,
-> stu.sn,
-> stu.NAME,
-> stu.qq_mail,
-> sco.score,
-> sco.course_id,
-> cou.NAME
-> FROM
-> student stu
-> LEFT JOIN score sco ON stu.id = sco.student_id
-> LEFT JOIN course cou ON sco.course_id = cou.id
-> ORDER BY
-> stu.id;
+----+-------+------------+------------------+-------+-----------+--------------+
| id | sn | NAME | qq_mail | score | course_id | NAME |
+----+-------+------------+------------------+-------+-----------+--------------+
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 70.5 | 1 | Java |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 98.5 | 3 | 计算机原理 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 33.0 | 5 | 高阶数学 |
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 98.0 | 6 | 英文 |
| 2 | 835 | 菩提老祖 | NULL | 60.0 | 1 | Java |
| 2 | 835 | 菩提老祖 | NULL | 59.5 | 5 | 高阶数学 |
| 3 | 391 | 白素贞 | NULL | 33.0 | 1 | Java |
| 3 | 391 | 白素贞 | NULL | 68.0 | 3 | 计算机原理 |
| 3 | 391 | 白素贞 | NULL | 99.0 | 5 | 高阶数学 |
| 4 | 31 | 许仙 | xuxian@qq.com | 67.0 | 1 | Java |
| 4 | 31 | 许仙 | xuxian@qq.com | 23.0 | 3 | 计算机原理 |
| 4 | 31 | 许仙 | xuxian@qq.com | 56.0 | 5 | 高阶数学 |
| 4 | 31 | 许仙 | xuxian@qq.com | 72.0 | 6 | 英文 |
| 5 | 54 | 不想毕业 | NULL | 81.0 | 1 | Java |
| 5 | 54 | 不想毕业 | NULL | 37.0 | 5 | 高阶数学 |
| 6 | 51234 | 好好说话 | say@qq.com | 56.0 | 2 | 中国传统文化 |
| 6 | 51234 | 好好说话 | say@qq.com | 43.0 | 4 | 语文 |
| 6 | 51234 | 好好说话 | say@qq.com | 79.0 | 6 | 英文 |
| 7 | 83223 | tellme | NULL | 80.0 | 2 | 中国传统文化 |
| 7 | 83223 | tellme | NULL | 92.0 | 6 | 英文 |
| 8 | 9527 | 老外学中文 | foreigner@qq.com | NULL | NULL | NULL |
+----+-------+------------+------------------+-------+-----------+--------------+
21 rows in set (0.00 sec)
自连接是在特殊情况下的特殊操作,不是一般用法。
SQL 中进行条件查询,都是指定某一列或者多个列之间进行关系运算,无法进行行与行之间的关系运算。有时候为了实现这种行之前的比较,就需要将行关系转换为列关系。
示例:
mysql> select * from score;
+----+-------+------------+-----------+
| id | score | student_id | course_id |
+----+-------+------------+-----------+
| 1 | 70.5 | 1 | 1 |
| 2 | 98.5 | 1 | 3 |
| 3 | 33.0 | 1 | 5 |
| 4 | 98.0 | 1 | 6 |
| 5 | 60.0 | 2 | 1 |
| 6 | 59.5 | 2 | 5 |
| 7 | 33.0 | 3 | 1 |
| 8 | 68.0 | 3 | 3 |
| 9 | 99.0 | 3 | 5 |
| 10 | 67.0 | 4 | 1 |
| 11 | 23.0 | 4 | 3 |
| 12 | 56.0 | 4 | 5 |
| 13 | 72.0 | 4 | 6 |
| 14 | 81.0 | 5 | 1 |
| 15 | 37.0 | 5 | 5 |
| 16 | 56.0 | 6 | 2 |
| 17 | 43.0 | 6 | 4 |
| 18 | 79.0 | 6 | 6 |
| 19 | 80.0 | 7 | 2 |
| 20 | 92.0 | 7 | 6 |
+----+-------+------------+-----------+
20 rows in set (0.00 sec)
比如说我要查询course_id为1的课程比course_id为2的课程分数高的学生的学生id。
mysql> select * from score as s1, score as s2 where s1.student_id = s2.student_id and s1.course_id = 1 and s2.course_id = 3;
+----+-------+------------+-----------+----+-------+------------+-----------+
| id | score | student_id | course_id | id | score | student_id | course_id |
+----+-------+------------+-----------+----+-------+------------+-----------+
| 1 | 70.5 | 1 | 1 | 2 | 98.5 | 1 | 3 |
| 7 | 33.0 | 3 | 1 | 8 | 68.0 | 3 | 3 |
| 10 | 67.0 | 4 | 1 | 11 | 23.0 | 4 | 3 |
+----+-------+------------+-----------+----+-------+------------+-----------+
3 rows in set (0.00 sec)
注意:自连接一定要将表重新命名,保证连接的两个表的名字是不同的
mysql> select * from score as s1, score as s2 where s1.student_id = s2.student_id and s1.course_id = 1 and s2.course_id = 3 and s1.score> s2.score;
+----+-------+------------+-----------+----+-------+------------+-----------+
| id | score | student_id | course_id | id | score | student_id | course_id |
+----+-------+------------+-----------+----+-------+------------+-----------+
| 10 | 67.0 | 4 | 1 | 11 | 23.0 | 4 | 3 |
+----+-------+------------+-----------+----+-------+------------+-----------+
1 row in set (0.00 sec)
子查询在实际开发过程中也要慎重。因为嵌套层次多了,对于代码可读性而言会变差。
示例:
查询与“不想毕业”同学同班的同学
mysql> select * from student where student.classes_id = (select classes_id from student where student.name = "不想毕业");
+----+------+------------+-----------------+------------+
| id | sn | name | qq_mail | classes_id |
+----+------+------------+-----------------+------------+
| 1 | 9982 | 黑旋风李逵 | xuanfeng@qq.com | 1 |
| 2 | 835 | 菩提老祖 | NULL | 1 |
| 3 | 391 | 白素贞 | NULL | 1 |
| 4 | 31 | 许仙 | xuxian@qq.com | 1 |
| 5 | 54 | 不想毕业 | NULL | 1 |
+----+------+------------+-----------------+------------+
5 rows in set (0.00 sec)
查询“语文”或“英文”课程的成绩信息
mysql> select id from course where name = "英文" or name = "语文";
+----+
| id |
+----+
| 4 |
| 6 |
| 10 |
| 12 |
+----+
4 rows in set (0.00 sec)
mysql> select * from score where score.id in (4,6,10,12);
+----+-------+------------+-----------+
| id | score | student_id | course_id |
+----+-------+------------+-----------+
| 4 | 98.0 | 1 | 6 |
| 6 | 59.5 | 2 | 5 |
| 10 | 67.0 | 4 | 1 |
| 12 | 56.0 | 4 | 5 |
+----+-------+------------+-----------+
4 rows in set (0.00 sec)
用一行代码来完成就是
mysql> select * from score where course_id in(select id from course where name = "英文"or name = "语文");
+----+-------+------------+-----------+
| id | score | student_id | course_id |
+----+-------+------------+-----------+
| 17 | 43.0 | 6 | 4 |
| 4 | 98.0 | 1 | 6 |
| 13 | 72.0 | 4 | 6 |
| 18 | 79.0 | 6 | 6 |
| 20 | 92.0 | 7 | 6 |
+----+-------+------------+-----------+
5 rows in set (0.00 sec)
在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。
语法:
select 列名1、列名2..... from 表名1 where条件1 union select 列名3、列名4.....from 表名2 where 条件2;
select 列名1、列名2..... from 表名1 where条件1 union all select 列名3、列名4.....from 表名2 where 条件2;
mysql> select * from course where id<3 or name = "英文";
+----+--------------+
| id | name |
+----+--------------+
| 1 | Java |
| 2 | 中国传统文化 |
| 6 | 英文 |
| 12 | 英文 |
+----+--------------+
4 rows in set (0.01 sec)
mysql> select * from course where id<3 union select * from course where name = '英文';
+----+--------------+
| id | name |
+----+--------------+
| 1 | Java |
| 2 | 中国传统文化 |
| 6 | 英文 |
| 12 | 英文 |
+----+--------------+
4 rows in set (0.01 sec)
SQL的基本操作的详解就到这里了。如果真的有一字不漏看到这里的小伙伴,相信你是有收获的。