SQL集合运算

ops/2024/11/17 19:06:17/

 集合论是SQL语言的根基。

1 集合运算

注意事项:

1)SQL能操作具有重复行的集合,可以通过可选项ALL来支持。

如果直接使用UNION或INTERSECT,结果里不会出现重复的行。如果想在结果里留下重复行,可以加上可选项ALL。写作UNION ALL。

集合运算符为了排除掉重复行,会默认发生排序,而加上可选项ALL之后,就不会再排序了,所以性能会提升。

2) 集合运算符有优先级。

INTERSECT比UNION和EXCEPT的优先级更高。

1.1 实践

1.1.1 检查集合相等性

图 两个集合t_table_a与t_table_b

-- UNION,如果合并后与两个集合的行数一致,则两个集合相同
SELECT CASE 
WHEN COUNT(*) = (SELECT COUNT(*) FROM t_table_a)
AND COUNT(*) = (SELECT COUNT(*) FROM t_table_b) 
THEN '集合相等'  ELSE '集合不相等' END AS res 
FROM 
(SELECT *
FROM t_table_a
UNION
SELECT *
FROM t_table_b)tmp
-- 集合运算,如果A与B的并集等于A与B的交集。 则A=B
SELECT CASE WHEN COUNT(*) = 0 THEN '相等' ELSE '不相等' END AS res
FROM 
((SELECT *
FROM t_table_a
UNION 
SELECT *
FROM t_table_b)
EXCEPT 
(SELECT *FROM t_table_aINTERSECT SELECT *FROM t_table_b
))tmp;

1.1.2 用差集实现关系除法运算

图 员工技能t_emp_skills 表与技能t_skills 表及期望输出

需求:找出精通t_skills 表所有技能的员工。

-- 差集 EXCEPT
SELECT DISTINCT emp 
FROM t_emp_skills e 
WHERE NOT EXISTS 
(SELECT skillFROM t_skillsEXCEPT SELECT skill FROM t_emp_skills WHERE emp = e.emp 
);	

需求:找出刚好拥有全部技术的员工(即擅长的技能和技能表的一摸一样,不多也不少)。

SELECT emp 
FROM t_emp_skills e 
WHERE NOT EXISTS ((SELECT skillFROM t_skills EXCEPT SELECT skill FROM t_emp_skillsWHERE emp = e.emp)
)
GROUP BY emp 
HAVING COUNT(*) = (SELECT COUNT(*) FROM t_skills);

1.1.3 寻找相等的子集

图 供应商-零件关系t_sup_parts表及期望输出

需求:找出经营的零件在种类数和种类上都完全相同的供应商组合。

SELECT s1.sup sup1,s2.sup sup2
FROM t_sup_parts s1
CROSS JOIN t_sup_parts s2 
WHERE s1.sup < s2.sup AND s1.part = s2.part
GROUP BY s1.sup,s2.sup
HAVING COUNT(*) = (SELECT COUNT(*) FROM t_sup_parts WHERE sup = s1.sup)
AND COUNT(*) = (SELECT COUNT(*) FROM t_sup_parts WHERE sup = s2.sup);

1.1.4 高效删除重复行

图 存在重复数据的t_fruit_info表

需求:删除表中重复的数据。

-- 使用关联子查询
DELETE FROM t_fruit_info f
WHERE row_id < (SELECT *FROM (SELECT MAX(row_id)FROM t_fruit_info WHERE `name` = f.name AND price = f.price) temp
);

关联子查询性能比较差。

-- 用差集运算 
DELETE FROM t_fruit_info
WHERE row_id IN (SELECT * FROM (SELECT row_idFROM t_fruit_info EXCEPT (SELECT row_idFROM t_fruit_infoGROUP BY `name`,price)) tmp
);
-- NOT IN 求补集 
DELETE FROM t_fruit_info
WHERE row_id NOT IN (SELECT * FROM (SELECT MAX(row_id)FROM t_fruit_info GROUP BY `name`,price) tmp
);

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

相关文章

推荐15个2024最新精选wordpress模板

以下是推荐的15个2024年最新精选WordPress模板&#xff0c;轻量级且SEO优化良好&#xff0c;适合需要高性能网站的用户。中文wordpress模板适合搭建企业官网使用。英文wordpress模板&#xff0c;适合B2C网站搭建&#xff0c;功能强大且兼容性好&#xff0c;是许多专业外贸网站的…

鸿蒙5.0版开发:使用HiLog打印日志(ArkTS)

在HarmonyOS 5.0中&#xff0c;HiLog是系统提供的一个日志系统&#xff0c;它允许应用和服务按照指定的级别、标识和格式字符串输出日志内容&#xff0c;帮助开发者了解应用的运行状态&#xff0c;更好地调试程序。本文将详细介绍如何在ArkTS中使用HiLog打印日志&#xff0c;并…

qt-5.11.3交叉编译

准备环境和工具 1、主机环境 ubuntu20 2、交叉编译器 gcc-linaro-6.3.1..arm-linux-gnuebihf 3、QT5源码包qt-5.11.3_sources 下载qt-5.11.3的包需要先带网络代理软件&#xff0c;再访问下载目录就可以显示了。 Index of /archive/qt 4、依赖库安装 sudo apt install g m…

单片机 串口实验 实验五

实验五 串口实验 一、实验目的 1、掌握MCS-51单片机串口通信的原理。 2、掌握MCS-51单片机串口通信程序的设计方法及其过程。 3、掌握MCS-51单片机串口通信的电路应用。 二、实验任务 两片单片机分别接一个按键和两个数码管&#xff0c;通过串口通信&#xff0c;实现单…

【学习】HTTP

HTTP 超文本传输协议&#xff08;HTTP&#xff09;是一个用于传输超媒体文档&#xff08;例如 HTML&#xff09;的应用层协议。它是为 Web 浏览器与 Web 服务器之间的通信而设计的&#xff0c;但也可以用于其他目的。HTTP 遵循经典的客户端—服务端模型&#xff0c;客户端打开…

C/C++ 中有哪些类型转换方式? 分别有什么区别?

在C编写C/C代码的时候&#xff0c;我们经常会遇到发生类型转换的场景&#xff0c;比如 赋值运算符的两个操作数不同、实参和形参类型不同、函数返回值类型和接收返回值的类型不同&#xff0c;都会发生类型转换&#xff1b;所以&#xff0c;在C语言中提供了两种类型转换 —— 隐…

CSM32RV20:RISC-V核的低功耗MCU芯片,常用在智能门锁上

CSM32RV20是一款基于RISC-V核的低功耗MCU芯片。 内置RISC-V RV32IMAC内核&#xff08;2.6CoreMark/MHz&#xff09;&#xff1b; 蕞高32MHz工作频率&#xff1b; 内置4kB的SRAM&#xff1b; 内置8B的ALWAYS寄存器&#xff0c;能在掉电模式2下保存数据&#xff1b; 内置40kB的嵌…

【Rust调用Windows API】获取正在运行的全部进程信息

前言 WIndows API官方文档 提供了C的调用示例&#xff0c;最近想尝试用Rust去实现&#xff0c;本系列博客记录一下实现过程。 依赖 Rust调用Windows API需要引入依赖winapi&#xff0c;在Cargo.toml中添加依赖 winapi "0.3.9"调用不同的API集就需要使用相应的功…