持续学习&持续更新中…
学习态度:守破离
DQL语句_主键外键_多表查询_JOIN_排序_分页
DQL语句
什么是DQL语句
聚合函数
常见的WHERE子句
比较运算
逻辑运算
模糊查询
UNIQUE KEY(索引)
主键(PRIMARY KEY)
什么是主键
什么是复合主键
外键(FOREIGN KEY)
什么是外键
为什么需要外键
请比较下面两种建表方式。很明显,第二种方式建表更好一点。
建表方式一:
建表方式二:
创建客户表和公司表
注意:
- 上面的建表语句表示:如果customer表中的company_id有值的话,它的值必须来自company表中的id字段。
- 当然,company_id是可以为空的,表示这个客户没有公司。
- 如果想要该客户必须设置公司的话,那么你也可以给customer表中的company_id后面加上NOT NULL(这样就能保证customer中的客户一定有company_id并且一定都是来自company表中)
级联
注意:
- 如果不写ON UPDATE CASCADE的话,那么就更新不了company下的id(如果该id已经被引用的话)
- 如果不写ON DELETE CASCADE的话,那么就删除不了company下的id(如果该id已经被引用的话)
测试代码:
CREATE TABLE company(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL UNIQUE,
address VARCHAR(20)
);
CREATE TABLE customer(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
age INT,
company_id INT,
FOREIGN KEY (company_id) REFERENCES company(id) # ON UPDATE CASCADE
);
INSERT INTO company(name, address) VALUES('阿里巴巴', '杭州');
INSERT INTO company(name, address) VALUES('腾讯', '深圳');
INSERT INTO customer(name, age, company_id) VALUES('张三', 22, 1);
INSERT INTO customer(name, age, company_id) VALUES('李四', 12, 2);
INSERT INTO customer(name, age, company_id) VALUES('王五', 23, 1);
INSERT INTO customer(name, age, company_id) VALUES('赵六', 33, 2);
INSERT INTO customer(name, age, company_id) VALUES('田七', 29, 1);
UPDATE company SET id = 11 WHERE id = 1;
多表查询
多表查询总纲
ON和WHERE区别
① ON
ON是配合JOIN使用的,是用来指定连接表的条件的。
图示中交集的数据都是符合ON之后条件的数据。
符合ON的一定是A和B的交集,A和B的交集一定是符合ON的。
② WHERE
-
WHERE的作用就是在前面连接查询的查询结果的基础上再进行一次过滤筛选操作
-
WHERE在这儿是用于限定从内连接或者外连接中查询出的数据之中的哪些数据应该出现在结果集中。
SELECT
*
FROM
customer a LEFT JOIN company b
ON
a.company_id = b.id
WHERE # 在之前查询的基础上进行一次过滤操作
b.name LIKE '%移动%';
数据准备
建表
customer表(100条数据):
CREATE TABLE customer(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(10) NOT NULL,
phone VARCHAR(20),
company_id INT,
FOREIGN KEY (company_id) REFERENCES company(id)
);
company表(20条数据):
CREATE TABLE company(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(10) NOT NULL,
address VARCHAR(100)
);
查询结果说明
① 这样查询出来的结果是两张表的笛卡尔积,会有2000(20 * 100)条结果。
SELECT * FROM company, customer;
② company_id不为NULL的客户有76个。
SELECT
*
FROM
customer
WHERE
company_id IS NOT NULL;
③ company_id为NULL的客户有24个。
SELECT
*
FROM
customer
WHERE
company_id IS NULL;
④ 有2个公司下面没有任何客户
⑤ 查出两张表之间有联系的部分。
# 76条
SELECT
*
FROM
customer, company
WHERE
customer.company_id = company.id;
SQL JOINS
注意:要想使用JOIN连接两张表,必须搞清楚这两张表之间的联系是什么,也就是必须要使用ON关键字来写清楚连接两张表的条件。(ON的意思就是:在什么条件的基础上进行两张表的连接)
说明:
- A、B代表两张表。A圈中是A的数据,B圈中是B的数据。
- 交叉区域:A表和B表之间有联系的数据。也就是取两张表的交集。交集都是符合ON条件的数据,符合ON条件的数据也一定在交集中。
- **交叉区域是两张表存在联系的数据,是两张表相互关联的数据,仅仅代表两张表的交集部分。**不要看下图RIGHT JOIN时觉得查询出来的数据就是B表中的数据,原因在于A表和B表是一对多的关系。
- 蓝色的区域代表能够查出来的数据。
- 蓝色区域大小不能说明数据多少,只是用来表示有这样的数据。(交集看起来比较小,但是有可能数据多。其他蓝色区域同理)
外连接
LEFT JOIN
左外连接:以左边的表为主。
结果集 = 两表有联系的数据(交集) + 左表独有的数据
结果集 = 符合ON条件的数据 + 左表中不符合ON的数据
# 100 = 76 + 24
# 100条数据
SELECT
*
FROM
# 以左边(customer)为主
customer a LEFT JOIN company b
ON
a.company_id = b.id;
蓝色区域中:A和B的交集部分是A表和B表之间有联系的数据(76);A减去交集的部分是A、B表没有联系但存在于A表中的数据(24条)。
RIGHT JOIN
右外连接:以右边的表为主。
结果集 = 两表有联系的数据(交集) + 右表独有的数据
结果集 = 符合ON条件的数据 + 右表中不符合ON的数据
# 78 = (76 + 2)
# 78条数据
SELECT
*
FROM
# 以右边(company)为主
customer a RIGHT JOIN company b
ON
a.company_id = b.id;
蓝色区域中:A和B的交集部分是A表和B表之间有联系的数据(76);B减去交集的部分是A、B表没有联系但存在于B表中的数据(2条)。
第三种情况
该情况的意思是在LEFT JOIN的基础上,查询出company.id为NULL时的数据。
# 24条
SELECT
*
FROM
customer a LEFT JOIN company b
ON
a.company_id = b.id
WHERE
b.id IS NULL;
观察LEFT JOIN查询出的数据不难看出:当company.id为NULL的时候,也就是customer.company_id为NULL的时候。(A、B表没有联系但存在于A表中的数据。也就是:从LEFT JOIN查询出来的数据中取出company.id为NULL时的数据)那么此时也可以使用如下语句来实现该查询:
# 24条
SELECT
*
FROM
customer
WHERE
company_id IS NULL;
第四种情况
该情况的意思是在RIGHT JOIN的基础上,查询出customer.company_id为NULL时的数据。
SELECT
*
FROM
customer a RIGHT JOIN company b
ON
a.company_id = b.id
WHERE
a.company_id IS NULL;
观察RIGHT JOIN查询出的数据不难看出:当customer.company_id为NULL的时候,也就是不存在该用户的时候,相当于查询出没有客户的公司。(A、B表没有联系但存在于B表中的数据。也就是:从LEFT JOIN查询出来的数据中取出customer.company_id为NULL时的数据)
内连接
内连接相当于查出两个表之间有联系的那些数据(图示中的交集区域)
结果集 = 符合ON的数据
# 76条
SELECT
*
FROM
customer a JOIN company b
ON
a.company_id = b.id;
FULL OUTER JOIN
情况一
左外连接:以左边的表为主。(两表有联系的数据 + 左表独有的数据)
右外连接:以右边的表为主。(两表有联系的数据 + 右表独有的数据)
FULL(全)外连接 = 左表独有的数据 + 两表有联系的数据 + 右表独有的数据
UNION就相当于取并集
# 102 = (76 + 24 + 2)
# 小括号可以不写
(
SELECT
*
FROM
customer a LEFT JOIN company b
ON
a.company_id = b.id
)
UNION
(
SELECT
*
FROM
customer a RIGHT JOIN company b
ON
a.company_id = b.id
);
情况二
# 26 = (24 + 2)条
SELECT
*
FROM
customer a LEFT JOIN company b
ON
a.company_id = b.id
WHERE
b.id IS NULL
UNION
SELECT
*
FROM
customer a RIGHT JOIN company b
ON
a.company_id = b.id
WHERE
a.company_id IS NULL;
排序、分页
排序
SELECT
*
FROM
student
WHERE id > 20
ORDER BY age DESC, id DESC; # 优先按照前面的进行升序降序
分页
-
注意:LIMIT(分页)语句要放在查询语句的最后。
-
分页查询:(左闭右开)
-
公式:LIMIT (n - 1) * pageSize, pageSize
# 假设每页15条(pageSize = 15)
# 假设查询第n页 (n >= 1)
# SELECT * FROM student LIMIT (n - 1) * pageSize, pageSize;
SELECT * FROM student LIMIT 0, 15; # 查询第一页
SELECT * FROM student LIMIT 15, 15; # 查询第二页
- 查询最前面的n条数据:
SELECT * FROM student LIMIT n;
- 计算总页数:
总数量:101条
每一页显示20条
公式:总页数 = (总数量 + 每页的数量 - 1) / 每页的数量
= ( 101 + 20 - 1) / 20
子查询
例子:查询出中国石油的所有客户信息
SELECT
*
FROM
customer
# 查询出来的结果只有一个可以使用 =
WHERE customer.company_id = (SELECT id FROM company WHERE name = '中国石油');
SELECT
*
FROM
customer
# 查询出来的结果有多个可以使用 IN
WHERE customer.company_id IN (SELECT id FROM company WHERE name LIKE '%移动%');
附—图示查询
参考
李明杰: Java从0到架构师②JavaEE技术基石.
本文完,感谢您的关注支持!