多表查询的分类与实现

ops/2024/12/19 11:06:57/

可能会出现的错误:

笛卡尔积的错误会在下面条件下产生

省略多个表的连接条件(或关联条件)

连接条件(或关联条件)无效

所有表中的所有行互相连接

如何避免: 可以WHERE 加入有效的连接条件。

WHERE子句中写入连接条件。

代码举例:

#多表查询如何实现
#出现笛卡尔积的错误
SELECT employee_id,department_name
FROM employees,departments;#查询出2889条数据------错误的
#每个员工都与每个部门匹配过----------------缺少多表的连接条件
SELECT employee_id,department_name
FROM employees CROSS JOIN departments;#------------------缺少连接条件#多表查询的正确方法,需要有连接条件
SELECT employee_id,department_name
FROM employees,departments
#多表的连接条件--------------------写在where中
WHERE employees.`department_id` = departments.`department_id`;

注意点:

》区分重复的列名

多个表中有相同列时,必须在列名之前加上表名前缀。

》利用表的别名,简化。(在from中表名的后面给表取一个简单的别名)

如果有n个表实现多表查询,则需要至少n-1个连接条件

连接的分类

》等值连接:使用等号的方式进行连接

》非等值连接:不使用等号的方式进行连接

》非自连接:不同表的连接

》自连接:同一张表,自己连接自己

》内连接:

 合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行

》外连接:

 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的

行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL)

如果是左外连接,则连接条件中左边的表也称为 主表 ,右边的表称为 从表

如果是右外连接,则连接条件中右边的表也称为 主表 ,左边的表称为 从表

》满外连接:即连接条件中左边的表,也条件中右边的表

》自然连接:NATURAL  JOIN

       内连接,不同表,有相同列名;自动将所有的不同表中相同列名连接

                                                                         ---------------------------不够灵活

代码举例:

#自然连接与USING连接
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`
AND e.`manager_id` = d.`manager_id`;
#等同与
SELECT employee_id,last_name,department_name
FROM employees e NATURAL JOIN departments d;
#将自然连接等价为等值连接,自动查询两张表中相同的字段--------------------将所有相同的列都算进来了,不够灵活

USING连接:JION  USING

        内连接,不同表,有相同列名,USING后面的括号中写明连接条件所需的列(该列需要时不同表中同名的列)

代码举例:

#USING连接
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`;
#等价与
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
USING (department_id);
#当两个字段(属于不同表的)同名时-------------连接条件

不同点:

自然连接 NATURAL JOIN 不同的是,USING 指定了具体的相同的字段名称,你需要在 USING

的括号 () 中填入要指定的同名字段。同时使用 JOIN...USING 可以简化 JOIN ON 的等值连接。

内连接(INNER JOIN)的实现

语法:

SELECT 字段列表

FROM AINNER JOIN B

ON 关联条件

WHERE 等其他子句;

代码举例:

#SQL99语法如何实现内连接 
#两个表的
SELECT last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id`=d.`department_id`;#三个表的----JOIN…ON 只能一对一对的使用不能 JOIN…ON…ON/JOIN …JOIN ..ON 连用
SELECT last_name,department_name,city
FROM employees e JOIN departments d
ON e.`department_id`=d.`department_id`
JOIN locations l
ON d.`location_id`=l.`location_id`;

也可以使用 :where   连接条件

SELECT employee_id,department_name
FROM employees,departments
WHERE employees.`department_id` = departments.`department_id`;

外连接(OUTER JOIN)的实现

#SQL92语法实现外连接:使用 + ------------------MySQL不支持SQL92语法中的外连接写法!

#SQL99语法中使用JOIN...ON 的方式实现多表的查询。这种方式也能解决外哦连接问题。MySQL支持此写法

左外连接(LEFT OUTER JOIN)

语法:

#实现查询结果是A

SELECT 字段列表

FROM ALEFT JOIN B

ON 关联条件

WHERE 等其他子句;

右外连接(RIGHT OUTER JOIN)

语法:

FROM ARIGHT JOIN B

ON 关联条件

WHERE 等其他子句;

代码举例:

#左外连接
SELECT employee_id,department_name 
FROM employees e LEFT JOIN departments d
ON e.`department_id`=d.`department_id`;#右外连接
SELECT employee_id,department_name 
FROM employees e RIGHT JOIN departments d
ON e.`department_id`=d.`department_id`;

满外连接(FULL OUTER JOIN)

满外连接的结果 = 左右表匹配的数据 + 左表没有匹配到的数据 + 右表没有匹配到的数据。

SQL99是支持满外连接的。使用FULL JOIN FULL OUTER JOIN来实现。

需要注意的是,MySQL不支持FULL JOIN但是可以用 LEFT JOIN UNION RIGHT join代替。

 

UNION的使用

合并查询结果 利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集合并。

注意:

》此时,两个表对应的列数和数据类型必须相同,并且相互对应。各个SELECT语句之间使用UNION或UNION  ALL关键字分隔。

》UNIONUNION 操作符返回两个查询的结果集的并集,去除重复记录。

UNION   ALLUNION ALL操作符返回两个查询的结果集的并集。对于两个结果集的重复部分,不去重。

格式:

SELECT column,... FROM table1

UNION [ALL]

SELECT column,... FROM table2

代码举例

SELECT employee_id,department_name 
FROM employees e LEFT JOIN departments d
ON e.`department_id`=d.`department_id`
UNION ALL
SELECT employee_id,department_name 
FROM employees e RIGHT JOIN departments d
ON e.`department_id`=d.`department_id`
WHERE e.`department_id`IS NULL;

总结:

表连接的约束条件可以有三种方式:WHERE, ON, USING

WHERE:适用于所有关联查询

ON :只能和JOIN一起使用,只能写关联条件。虽然关联条件可以并到WHERE中和其他条件一起

写,但分开写可读性更好。

USING:只能和JOIN一起使用,而且要求两个关联字段在关联表中名称一致,而且只能表示关联字

段值相等


http://www.ppmy.cn/ops/143162.html

相关文章

wxWidgets使用wxStyledTextCtrl(Scintilla编辑器)的正确姿势

开发CuteMySQL/CuteSqlite开源客户端的时候,需要使用Scintilla编辑器,来高亮显示SQL语句,作为C/C领域最成熟稳定又小巧的开源编辑器,Scintilla提供了强大的功能,wxWidgets对Scintilla进行包装后的是控件类:…

Web安全攻防入门教程——hvv行动详解

Web安全攻防入门教程 Web安全攻防是指在Web应用程序的开发、部署和运行过程中,保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现,还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。 本教程将带你入门Web安全攻…

灵当crm pdf.php存在任意文件读取漏洞

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…

Focal Loss损失函数理解

简介:Focal Loss损失函数是对交叉熵损失函数的升级。是和yolo配套的 因为yolo会对图像进行网格化处理,会分出正负样本,是多目标检测,而不是简单的分类问题 1. 对比交叉熵损失的区别 多分类:CrossEntropyLoss 公式&a…

Java集合(完整版)

集合框架 Collection集合 概念:对象的容器,定义了对多个对象进行操作的常用方法。可以实现数组的功能 和数组的区别: 数组的长度固定,集合长度不固定数组可以存储基本类型和引用类型,集合只能存储引用类型 Collec…

多进程并发跑程序:pytest-xdist记录

多进程并发跑程序:pytest-xdist记录 pytest -s E:\testXdist\test_dandu.py pytest -s testXdist\test_dandu.py pytest -s :是按用例顺序依次跑用例 pytest -vs -n auto E:\testXdist\test_dandu.py pytest -vs -n auto,auto表示以全部进程…

DCDC降压模块

一、项目介绍 在B站看到工科男孙老师发的DCDC模块视频,后面有提到这款芯片,于是就使用这款芯片自己设计了这款降压模块。 芯片的封装为TSOT23-8,对空间利用率高。 输入电压的范围为3-18V。 输出电压的范围为0-8V。 输出电流最…

etcd数据迁移

场景1 更换高性能盘 停掉etcd服务高性能盘上创建新的数据目录copy旧数据文件到新数据目录中修改配置文件的数据目录为新目录,然后重启服务 场景2 更换高性能物理机器,不停服切换 新的机器需要先安装好etcd服务先启动安装好的一台etcd,单独…