【技术积累】Mysql中的SQL高级技巧【一】
什么是多表查询?如何在MySQL中进行多表查询?
多表查询就是在一个查询中涉及到多个表,通过特定的关联方式连接多个表,并根据条件从中查询出所需要的数据。
多表查询是关系型数据库中最为基础的应用之一。
一个比较典型的例子就是,我们在查询一个订单的详细信息时,需要从订单表中获取订单编号,然后根据订单编号关联到商品表,获取商品信息,再根据商品信息关联到库存表中,查询商品数量。一个完整的查询操作需要同时查询多个表才能完整获取所需信息。
在MySQL中,进行多表查询的方式有多种,比较常用的有三种:内连接、左连接、右连接。其中:
- 内连接是一种常用的表连接方式,只有在两个表中都具有相同的数据时,才会将两个表进行连接。内连接包含四种:等值连接,非等值连接,自连接和多表连接。
 - 左连接也是一种常用的表连接方式,左连接会保留左表中的所有数据,并将右表中符合条件的数据进行匹配,如果没有匹配的数据则返回NULL。左连接只会返回左表中的数据。
 - 右连接和左连接很相似,只是保留的是右表的数据。
 
建表语句
# 1.订单表
CREATE TABLE orders (
id int(11) NOT NULL AUTO_INCREMENT,
order_num bigint(20) NOT NULL,
order_time datetime NOT NULL,
user_id int(11) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO orders (id, order_num, order_time, user_id)
VALUES
(1, 1111111, '2022-11-11 12:00:00', 1),
(2, 2222222, '2022-10-10 10:00:00', 2),
(3, 3333333, '2022-09-09 09:00:00', 3);
# 2.商品表
CREATE TABLE goods (
id int(11) NOT NULL AUTO_INCREMENT,
goods_name varchar(20) NOT NULL,
price decimal(10,2) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO goods (id, goods_name, price)
VALUES
(1, '商品1', 99.00),
(2, '商品2', 399.00),
(3, '商品3', 199.00);
# 3.订单商品关联表
CREATE TABLE order_goods (
id int(11) NOT NULL AUTO_INCREMENT,
order_id int(11) NOT NULL,
goods_id int(11) NOT NULL,
goods_num int(11) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO order_goods (id, order_id, goods_id, goods_num)
VALUES
(1, 1, 2, 2),
(2, 1, 3, 1),
(3, 2, 1, 3),
(4, 2, 2, 1),
(5, 3, 3, 2);
多表查询的SQL语句
# 1.查询订单表中所有订单的详细信息,包括订单编号、订单时间、用户ID、商品名称、商品价格、商品数量等。
SELECT o.order_num, o.order_time, o.user_id, g.goods_name, g.price, og.goods_num
FROM orders o
INNER JOIN order_goods og ON o.id = og.order_id
INNER JOIN goods g ON og.goods_id = g.id;
# 2.查询订单表中所有订单的详细信息,包括订单编号、订单时间、用户ID、商品名称、商品价格、商品数量等。但只显示2019-12-10之后的订单。
SELECT o.order_num, o.order_time, o.user_id, g.goods_name, g.price, og.goods_num
FROM orders o
INNER JOIN order_goods og ON o.id = og.order_id
INNER JOIN goods g ON og.goods_id = g.id
WHERE o.order_time >= '2019-12-10';
# 3.查询用户ID为1的用户所下的所有订单的详细信息,包括订单编号、订单时间、用户ID、商品名称、商品价格、商品数量等。
SELECT o.order_num, o.order_time, o.user_id, g.goods_name, g.price, og.goods_num
FROM orders o
INNER JOIN order_goods og ON o.id = og.order_id
INNER JOIN goods g ON og.goods_id = g.id
WHERE o.user_id = 1;
什么是子查询?如何在MySQL中进行子查询?
子查询是指在一个查询语句中嵌套另一个查询语句的过程。子查询可以作为一个完整的查询来使用,也可以作为其他查询的一个子部分。子查询可以返回一个值或一组值,这些值可以用来过滤主查询中的结果,或者作为主查询的一部分。
在MySQL中,可以使用子查询来执行复杂的数据查询和分析。子查询可以嵌套在SELECT、INSERT、UPDATE 和 DELETE等语句中。
下面是一些常用的MySQL子查询语句:
# 1.基本子查询语法
SELECT column1, column2, …
FROM table1
WHERE column1 = (SELECT column1 FROM table2 WHERE condition);
# 2.带IN操作符的子查询
SELECT column1, column2, …
FROM table1
WHERE column1 IN (SELECT column1 FROM table2 WHERE condition);
# 3.带EXISTS操作符的子查询
SELECT column1, column2, …
FROM table1
WHERE EXISTS (SELECT column1 FROM table2 WHERE condition);
现在,我们来看一个具体的例子:假设我们有两张表,一张是学生表,另一张是成绩表。学生表包含学生的信息,包括姓名、学号、性别等。成绩表包含学生的成绩信息,包括学号、科目、成绩等。我们通过子查询来查询某个学生的平均成绩和最高成绩。
CREATE TABLE student (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
gender ENUM('male', 'female') NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE score (
id INT NOT NULL AUTO_INCREMENT,
student_id INT NOT NULL,
course VARCHAR(50) NOT NULL,
grade INT NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO student (name, gender) VALUES
('Alice', 'female'),
('Bob', 'male'),
('Charlie', 'male');
INSERT INTO score (student_id, course, grade) VALUES
(1, 'math', 80),
(1, 'physics', 90),
(2, 'math', 85),
(2, 'physics', 95),
(3, 'math', 90),
(3, 'physics', 80);
现在,我们来写一个子查询,查询Bob的平均成绩和最高成绩:
SELECT name,
(SELECT AVG(grade) FROM score s WHERE s.student_id = student.id) AS avg_grade,
(SELECT MAX(grade) FROM score s WHERE s.student_id = student.id) AS max_grade
FROM student
WHERE name = 'Bob';
在这个例子中,我们使用了两个子查询来计算Bob的平均成绩和最高成绩。第一个子查询使用了AVG聚合函数来计算平均成绩,第二个子查询使用了MAX聚合函数来计算最高成绩。在子查询中,我们使用了WHERE子句来限制查询结果的范围,以便仅查询与当前学生相关的成绩。最后,我们把子查询的结果作为主查询的一部分输出。
总的来说,子查询是一个非常强大的工具,可以用来执行复杂的数据分析和查询。在MySQL中,子查询可以嵌套在其他查询中,以实现更灵活、更高效的数据查询和操作。
子查询和多表查询有什么区别?
子查询是在一个SQL语句中嵌套另一个完整的SELECT语句,用于提供一个参考对象或结果集,这个结果集将被嵌入到更大的查询中。它用于在一个查询中检索条件的子集,它可以被用于任意的SELECT, INSERT, UPDATE和DELETE语句中。
多表查询是指从多张表中检索信息的查询,它可以结合使用JOIN, UNION等等,以检索或计算来自多个表的特定数据集。多表查询经常用于大型数据库中,其中将数据分布在许多表中而不是一个表中。
主要区别在于:
子查询一般是单独的SQL语句,而多表查询通常涉及到多个表格。
子查询一般只返回一行,而多表查询可以返回多行。
子查询用于在一个查询中检索条件的子集,而多表查询则用于在多个表中联结,计算或筛选出需要的结果集。
子查询可以嵌套在其他语句中,而多表查询中嵌套其他SELECT语句时候通常使用JOIN等关键字。
在实际使用中,两种类型的查询可以结合使用,以实现更复杂和更灵活的数据库操作。
什么是联合查询?如何在MySQL中进行联合查询?
联合查询(Union)是将多个SELECT语句的结果合并成一个结果集输出的查询方式。它的关键字是UNION,它可以连接两个或多个SELECT语句的结果集,并去除重复数据。
在MySQL中进行联合查询,需要满足以下几个条件:
联合查询的每个SELECT语句的列数必须相同。
联合查询的每个SELECT语句的列名可以不同,但是需要用AS关键字定义别名。
联合查询的每个SELECT语句的列的数据类型必须相同或可自动转换。
CREATE TABLE `table1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `table1` (`id`, `name`, `age`) VALUES
(1, '张三', 18),
(2, '李四', 19),
(3, '王五', 20);
CREATE TABLE `table2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `table2` (`id`, `name`, `age`) VALUES
(1, '张三', 18),
(2, '李四', 19),
(3, '赵六', 22);
下面是一个SQL语句的示例,用于查询两个表的name和age列的联合结果,并去除重复数据:
SELECT name, age FROM table1
UNION
SELECT name, age FROM table2;
联合查询和多表查询有什么区别?
联合查询和多表查询都是SQL语言中用于从多个表中获取数据的查询方法,但它们的方式和作用略有不同。
联合查询(UNION)是指将两个或多个表中相同列的数据连接在一起,形成一个结果集。比如在两个表中查询出相同的列,可以使用UNION将它们合并成一个结果集。使用UNION操作时,查询语句必须返回相同的列名和数据类型,而且返回的结果集将自动去除重复行。
而多表查询(JOIN)是指用户可以使用SQL语言将多个表连接起来,形成一个虚拟的表,允许在其中进行查询或数据操作。其作用是将多张表中有关联的数据重新组合,从而可以更方便的查询和操作数据。在多表查询中有不同的连接类型,例如INNER JOIN(内连接)、LEFT JOIN(左连接)、RIGHT JOIN(右连接)等,它们表示不同的数据连接方式和结果集输出方式。
因此,联合查询和多表查询是两种不同的查询方式。联合查询适用于查询相同结构的数据集,而多表查询则适用于查询在多个相关表之间的数据。
什么是交叉查询?如何在MySQL中进行交叉查询?
交叉查询(Cross Join)是一种在数据库中组合两个或多个表的查询方法,即返回每个表的所有行的组合。交叉查询用于从多个表中检索数据,它返回两个(或更多)表的所有可能的组合。交叉查询不使用任何条件过滤数据,它仅仅是将数据组合在一起。
在MySQL中进行交叉查询,需要使用关键字“CROSS JOIN”或者省略掉关键字“CROSS”,直接使用“JOIN”。
下面是建立两个表的建表语句,我们用交叉查询找到这两个表的笛卡尔积:
CREATE TABLE table_a (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(10) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE table_b (
id int(11) NOT NULL AUTO_INCREMENT,
age int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO table_a (id, name) VALUES (1, '张三'), (2, '李四');
INSERT INTO table_b (id, age) VALUES (1, 20), (2, 30);
交叉查询语句:
SELECT * FROM table_a CROSS JOIN table_b;
SELECT * FROM table_a JOIN table_b;
交叉查询和多表查询有什么区别?
交叉查询和多表查询都用于从多个表中检索数据。但是,它们之间存在明显的区别。
交叉查询: 交叉查询也称为笛卡尔积查询。它是指从表中取出所有可能的组合并生成结果集。也就是说,交叉查询会返回一个表和另一个表中所有行的组合。如果有两个表,每个表都有10行,则结果集将包含100个行。交叉查询的结果集非常大,往往会消耗大量的时间和系统资源。通常不建议使用交叉查询。
多表查询: 多表查询指的是从多个表中检索有关联的数据。多表查询通常使用JOIN操作符将多个表连接起来,然后根据各个表之间的关系提取数据。JOIN操作符将返回一个表中的行与另一个表中的行相关联。根据JOIN操作符的类型,多表查询可以分为内连接、左连接、右连接和全连接。
总体来说,交叉查询的结果集包含了两个表中所有行的组合,而多表查询能够检索有相关联的数据。虽然交叉查询能够检索到所有数据,但它的结果往往特别冗长且不可操作。相反,多表查询更为常见,它能更精准地提取需要的数据,也能够更高效地操作数据。
【技术积累】Mysql中的SQL高级技巧【一】的更多相关文章
- MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause
		
MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause 201 ...
 - 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载
		
浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...
 - 【原创】6. 在MYSQL++中实现SQL语法中的NULL
		
这次要说明的是在MYSQL++中为了实现SQL中的NULL而做出的一系列的举措.我的感觉是Null<T, B>类型通常出现在SSQLS和template Query中比较多. 1. 什么是 ...
 - Mysql中的sql是如何执行的 --- 极客时间学习笔记
		
MySQL中的SQL是如何执行的 MySQL是典型的C/S架构,也就是Client/Server架构,服务器端程序使用的mysqld.整体的MySQL流程如下图所示: MySQL是有三层组成: 连接层 ...
 - MySQL中的SQL的常见优化策略
		
MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 1 避免全表扫描对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索 ...
 - mysql中的sql
		
变量 用户变量: 在用户变量前加@ 系统变量: 在系统变量前加@@ 运算符 算术运算符有: +(加), -(减), * (乘), / (除) 和% (求模) 五中运算 位运算符有: & (位于 ...
 - MySQL中关于SQL注入的相关需要的基础知识
		
零.绪论: 文章部分整理来源于公司同事,特此鸣谢!!! 一.关于注入点在KEY上的注入: 我们来看一个查询,你的第一个字段是过滤器(filter)第二个字段是查询的关键字,例如查询ip == 1.2. ...
 - MySQL中的SQL流程分析简述
		
分析MySQL中这条语句的整个流程 update table_a set c1=xx where c2=xxx 朋友考我的一个问题在此处列出个人见解 1 客户端连接进来首先进行权限验证 2 验证通过后 ...
 - 技术分享 | MySQL中MGR中SECONDARY节点磁盘满,导致mysqld进程被OOM Killed
		
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 在MGR测试中,人为制造磁盘满问题后,节点被oom killed 问题描述 在对 ...
 - 如何在MySql中记录SQL日志记录
		
My SQL可以用下面方法跟踪sql 语句,以下方法以Windows平台为例,linux雷同: 1 配置my.ini文件(在安装目录,linux下文件名为my.cnf 查找到[mysql ...
 
随机推荐
- Kali中python问题
			
Kali中python问题 1.查看python有哪些版本 update-alternatives --display python 2.如果没有,可以去/usr/bin查看kali自带哪些版本 查看 ...
 - GitHub+Typora实现云笔记一键上传
			
git实现笔记自动上传功能 简介: 将更新内容自动上传同步git,无需手动提交,解锁一键式同步.流程大致为,创建新仓库,配置公钥和私钥,安装quicker软件,通过quicker上某脚本完成一键提交. ...
 - Flask框架使用蓝图划分目录、g对象、使用数据库连接池链接数据库
			
目录 一.使用蓝图划分项目目录 1.蓝图的介绍 2.蓝图的使用 二.介绍flask框架的g对象 1. g对象是什么? 2. 使用代码再次解释g对象 三.使用数据库连接池链接数据库 1. 引入数据库连接 ...
 - 使用 Istioctl 安装 istio
			
使用 Istioctl 安装 istio 下载 Istio 转到 Istio 发布 页面,下载针对你操作系统的安装文件, 或用自动化工具下载并提取最新版本(Linux 或 macOS): [root@ ...
 - [Git]git分支查询——图像化[转载]
			
1 git reflog git reflog : 可查看所有分支的所有操作记录(含: commit / reset / merge / checkout等操作) 1-1 查看分支的所有变更记录(含: ...
 - day08 元组字典集合
			
day08 元组 集合 字典 元组 """ 小括号括起来,内部存放多个元素,元组之间逗号隔开,元素不可改变,元素类型不能是任意的, """ ...
 - React+Antd在使用form表单提交DatePicker日期框的时候会出现少八小时的情况
			
在使用antd做form表单提交的时候,突然发现了一个很有意思的bug.就是在使用datepicker组件日期框的时候会出现提交后少一天的问题 我在网上搜索了许多解决办法,也是困扰了我一天的时间,下面 ...
 - CSS页面布局方式
			
css页面布局方式 1.标准流 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
 - 关于Java中对象的向上转型和向下转型
			
什么是多态? 同一个类调用同一个方法会产生不同的影响/结果 这就是多态 public class Pet{ public void eat(){ System.out.println("Pe ...
 - js复制功能(pc复制,移动端复制到手机剪切板)
			
一个函数,直接调就好了,已测pc和app都适用 1 // 一键复制 2 copyBtn(data) { 3 const input = document.createElement("inp ...