草庐IT

读SQL进阶教程笔记04_集合运算

躺柒 2023-04-01 原文

1. 集合论是SQL语言的根基

1.1. UNION

  • 1.1.1. SQL-86标准

1.2. NTERSECT和EXCEPT

  • 1.2.1. SQL-92标准

1.3. 除法运算(DIVIDE BY)

  • 1.3.1. 没有被标准化

2. 注意事项

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

  • 2.1.1. 不允许重复

    • 2.1.1.1. 直接使用UNION或INTERSECT

    • 2.1.1.2. 集合运算符为了排除掉重复行,默认地会发生排序

  • 2.1.2. 允许重复

    • 2.1.2.1. 加上可选项ALL

      2.1.2.1.1. 不会再排序,所以性能会有提升

      2.1.2.1.2. 非常有效的用于优化查询性能的方法

    • 2.1.2.2. UNION ALL

      2.1.2.2.1. 不具有幂等性

2.2. 集合运算符有优先级

  • 2.2.1. INTERSECT比UNION和EXCEPT优先级更高

  • 2.2.2. 括号明确地指定运算顺序

2.3. 各个DBMS提供商在集合运算的实现程度上参差不齐

  • 2.3.1. SQL Server从2005版开始支持INTERSECT和EXCEPT

  • 2.3.2. Oracle这样,实现了EXCEPT功能但却命名为MINUS的数据库

  • 2.3.3. INTERSECT和EXCEPT不能在MySQL里执行

2.4. 除法运算没有标准定义

  • 2.4.1. 四则运算里的和(UNION)、差(EXCEPT)、积(CROSS JOIN)都被引入了标准SQL

3. 检查集合相等性

3.1. “相等”指的是行数和列数以及内容都相同

3.2. “是同一个集合”

3.3. 原理1

  • 3.3.1. S UNION S = S

  • 3.3.2. 幂等性(indempotency)

    • 3.3.2.1. 抽象代数里群论等理论中的概念

    • 3.3.2.2. 二目运算符对任意S,都有SS = S成立”

3.4. 示例1

  • 3.4.1.
  SELECT COUNT(*) AS row_cnt
     FROM ( SELECT *
             FROM tbl_A
           UNION
           SELECT *
             FROM tbl_B ) TMP;
  • 3.4.2. 这个查询的结果与tbl_A及tbl_B的行数一致,则两张表是相等的

  • 3.4.3. 表tbl_A和表tbl_B的行数是一样的

    • 3.4.3.1. 如果行数不一样,那就不需要比较其他的了

3.5. 原理2

  • 3.5.1. 如果A UNION B = A INTERSECT B,则集合A和集合B相等

  • 3.5.2. (A UNION B) EXCEPT (A INTERSECT B)的结果集是不是空集就可以了

  • 3.5.3. INTERSECT

    • 3.5.3.1. 幂等性(indempotency)
  • 3.5.4. EXCEPT不具有幂等性

3.6. 示例2

  • 3.6.1. --两张表相等时返回“相等”,否则返回“不相等”
   SELECT CASE WHEN COUNT(*) = 0
               THEN ’相等’
               ELSE’不相等’END AS result
     FROM ((SELECT * FROM  tbl_A
           UNION
           SELECT * FROM  tbl_B)
           EXCEPT
           (SELECT * FROM  tbl_A
           INTERSECT
           SELECT * FROM  tbl_B)) TMP;
  • 3.6.2. 改进版不需要事先查询两张表的行数

  • 3.6.3. 需要进行4次排序(3次集合运算加上1次DISTINCT)

    • 3.6.3.1. 性能会有所下降

3.7. 示例3

  • 3.7.1. --用于比较表与表的diff
   (SELECT * FROM  tbl_A
    EXCEPT
    SELECT * FROM  tbl_B)
   UNION ALL
   (SELECT * FROM  tbl_B
    EXCEPT
    SELECT * FROM  tbl_A);

4. 用差集实现关系除法运算

4.1. 嵌套使用NOT EXISTS

4.2. 使用HAVING子句转换成一对一关系

4.3. 把除法变成减法

  • 4.3.1. 示例

    • 4.3.1.1.


  • 4.3.1.2. --用求差集的方法进行关系除法运算(有余数)
   SELECT DISTINCT emp
     FROM EmpSkills ES1
    WHERE NOT EXISTS
           (SELECT skill
             FROM Skills
           EXCEPT
           SELECT skill
             FROM EmpSkills ES2
             WHERE ES1.emp = ES2.emp);
  • 4.3.1.3. 关联子查询是为了使SQL能够实现类似面向过程语言中循环的功能而引入的

5. 寻找相等的子集

5.1. IBM过去研制的第一个关系数据库实验系统——System R

  • 5.1.1. 用CONTAINS这一谓词来检查集合间的包含关系

  • 5.1.2. 后来因为性能原因被删除掉了,直到现在也没有恢复

  • 5.1.3.

SELECT 'A CONTAINS B'

     FROM SupParts
    WHERE (SELECT part
             FROM SupParts
           WHERE  sup ='A')
             CONTAINS
                 (SELECT part
                   FROM SupParts
                   WHERE  sup ='B')

5.2. 示例

  • 5.2.1. --生成供应商的全部组合
   SELECT SP1.sup AS s1, SP2.sup AS s2
     FROM SupParts SP1, SupParts SP2
    WHERE SP1.sup < SP2.sup
    GROUP BY SP1.sup, SP2.sup;
  • 5.2.2.
SELECT SP1.sup AS s1, SP2.sup AS s2

     FROM SupParts SP1, SupParts SP2
    WHERE SP1.sup < SP2.sup                  --生成供应商的全部组合
     AND SP1.part = SP2.part                --条件1:经营同种类型的零件
    GROUP BY SP1.sup, SP2.sup
   HAVING COUNT(*) = (SELECT COUNT(*)       --条件2:经营的零件种类数相同
                       FROM SupParts SP3
                       WHERE SP3.sup = SP1.sup)
     AND COUNT(*) = (SELECT COUNT(*)
                       FROM SupParts SP4
                       WHERE SP4.sup = SP2.sup);
  • 5.2.3. SQL在比较两个集合时,并不是以行为单位来比较的,而是把集合当作整体来处理的

6. 用于删除重复行的高效SQL

6.1. --删除重复行:使用关联子查询

    DELETE FROM Products
     WHERE rowid < ( SELECT MAX(P2.rowid)
                      FROM Products P2
                      WHERE Products.name  = P2. name
                        AND Products.price = P2.price ) ;

6.2. --用于删除重复行的高效SQL语句(1):通过EXCEPT求补集

    DELETE FROM Products
     WHERE rowid IN ( SELECT rowid           --全部rowid
                        FROM Products
                      EXCEPT                 --减去
                      SELECT MAX(rowid)     --要留下的rowid
                        FROM Products
                      GROUP BY name, price) ;

6.3. --删除重复行的高效SQL语句(2):通过NOT IN求补集

    DELETE FROM Products
     WHERE rowid NOT IN ( SELECT MAX(rowid)
                            FROM Products
                          GROUP BY name, price);
  • 6.3.1. 不支持EXCEPT的数据库也可以使用

6.4. 实现了行ID的数据库只有Oracle和PostgreSQL

  • 6.4.1. PostgreSQL里的相应名字是oid,如果要使用,需要事先在CREATE TABLE的时候指定可选项WITH OIDS

  • 6.4.2. 如果其他数据库想要使用这些SQL,则需要在表中创建类似的具有唯一性的“id”列

有关读SQL进阶教程笔记04_集合运算的更多相关文章

  1. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  2. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  3. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  4. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  5. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  6. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  7. hadoop安装之保姆级教程(二)之YARN的配置 - 2

    1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模

  8. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

  9. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  10. ruby - 带括号和 splat 运算符的并行赋值 - 2

    我明白了:x,(y,z)=1,*[2,3]x#=>1y#=>2z#=>nil我想知道为什么z的值为nil。 最佳答案 x,(y,z)=1,*[2,3]右侧的splat*是内联扩展的,所以它等同于:x,(y,z)=1,2,3左边带括号的列表被视为嵌套赋值,所以它等价于:x=1y,z=23被丢弃,而z被分配给nil。 关于ruby-带括号和splat运算符的并行赋值,我们在StackOverflow上找到一个类似的问题: https://stackoverflow

随机推荐