SQL入门 |
您所在的位置:网站首页 › 集合运算减号什么意思 › SQL入门 |
集合运算-表的加减法和join
4.1表的加减法
4.1.1 什么是集合运算
集合在数学领域表示“各种各样的事物的总和”, 在数据库领域表示记录的集合. 具体来说,表、视图和查询的执行结果都是记录的集合, 其中的元素为表或者查询结果中的每一行。 在标准 SQL 中, 分别对检索结果使用 UNION, INTERSECT, EXCEPT 来将检索结果进行并,交和差运算, 像UNION,INTERSECT, EXCEPT这种用来进行集合运算的运算符称为集合运算符。 以下的文氏图展示了几种集合的基本运算. 在数据库中, 所有的表–以及查询结果–都可以视为集合, 因此也可以把表视为集合进行上述集合运算, 在很多时候, 这种抽象非常有助于对复杂查询问题给出一个可行的思路. 4.1.2 表的加法–UNION 4.1.2.1 UNION接下来我们演示UNION的具体用法及查询结果: SELECT product_id, product_name FROM product UNION SELECT product_id, product_name FROM product2;上述结果包含了两张表中的全部商品. 你会发现,这就是我们在学校学过的集合中的并集运算,通过文氏图会看得更清晰(图 7-1): 通过观察可以发现,商品编号为“ 0001 ”~“ 0003 ”的 3 条记录在两个表中都存在,因此大家可能会认为结果中会出现重复的记录,但是 UNION 等集合运算符通常都会除去重复的记录. 上述查询是对不同的两张表进行求并集运算. 对于同一张表, 实际上也是可以进行求并集的. **练习题:**假设连锁店想要增加毛利率超过 50%或者售价低于 800 的货物的存货量, 请使用 UNION 对分别满足上述两个条件的商品的查询结果求并集. 结果应该类似于: 思考: 如果不使用 UNION 该怎么写查询语句? -- 参考答案: SELECT product_id,product_name,product_type ,sale_price,purchase_price FROM product WHERE sale_price < 800 OR sale_price > 1.5 * purchase_price; 4.1.2.2UNION 与 OR 谓词对于同一个表的两个不同的筛选结果集, 使用 UNION 对两个结果集取并集, 和把两个子查询的筛选条件用 OR 谓词连接, 会得到相同的结果, 但倘若要将两个不同的表中的结果合并在一起, 就不得不使用 UNION 了. 而且, 即便是对于同一张表, 有时也会出于查询效率方面的因素来使用 UNION 练习题 : 分别使用 UNION 或者 OR 谓词,找出毛利率不足 30%或毛利率未知的商品. 参考答案: -- 使用 OR 谓词 SELECT * FROM product WHERE sale_price / purchase_price < 1.3 OR sale_price / purchase_price IS NULL; -- 使用 UNION SELECT * FROM product WHERE sale_price / purchase_price < 1.3 UNION SELECT * FROM product WHERE sale_price / purchase_price IS NULL; 4.1.2.3 包含重复行的集合运算 UNION ALL在 UNION 的结果中保留重复行的语法其实非常简单,只需要在 UNION 后面添加 ALL 关键字就可以了. 4.1.2.4[扩展阅读]bag 模型与 set 模型在高中数学课上我们就学过, 集合的一个显著的特征就是集合中的元素都是互异的. 当我们把数据库中的表看作是集合的时候, 实际上存在一些问题的: 不论是有意的设计或无意的过失, 很多数据库中的表包含了重复的行. Bag 是和 set 类似的一种数学结构, 不一样的地方在于: bag 里面允许存在重复元素, 如果同一个元素被加入多次, 则袋子里就有多个该元素. 通过上述 bag 与 set 定义之间的差别我们就发现, 使用 bag 模型来描述数据库中的表在很多时候更加合适. 是否允许元素重复导致了 set 和 bag 的并交差等运算都存在一些区别. 以 bag 的交为例, 由于 bag 允许元素重复出现, 对于两个 bag, 他们的并运算会按照: 1.该元素是否至少在一个 bag 里出现过, 2.该元素在两个 bag 中的最大出现次数 这两个方面来进行计算. 因此对于 A = {1,1,1,2,3,5,7}, B = {1,1,2,2,4,6,8} 两个 bag, 它们的并就等于 {1,1,1,2,2,3,4,5,6,7,8}. 4.1.2.5隐式类型转换通常来说, 我们会把类型完全一致, 并且代表相同属性的列使用 UNION 合并到一起显示, 但有时候, 即使数据类型不完全相同, 也会通过隐式类型转换来将两个类型不同的列放在一列里显示, 例如字符串和数值类型: SELECT product_id, product_name, '1' FROM product UNION SELECT product_id, product_name,sale_price FROM product2;上述查询能够正确执行,得到如下结果: 集合的交, 就是两个集合的公共部分, 由于集合元素的互异性, 集合的交只需通过文氏图就可以很直观地看到它的意义. 虽然集合的交运算在SQL标准中已经出现多年了, 然而很遗憾的是, 截止到 MySQL 8.0 版本, MySQL 仍然不支持 INTERSECT 操作. SELECT product_id, product_name 4.1.3.1[扩展阅读]bag 的交运算对于两个 bag, 他们的交运算会按照: 1.该元素是否同时属于两个 bag, 2.该元素在两个 bag 中的最小出现次数这两个方面来进行计算. 因此对于 A = {1,1,1,2,3,5,7}, B = {1,1,2,2,4,6,8} 两个 bag, 它们的交运算结果就等于 {1,1,2}. 4.1.4 差集,补集与表的减法求集合差集的减法运算和实数的减法运算有些不同, 当使用一个集合A减去另一个集合B的时候,对于只存在于集合B而不存在于集合A的元素, 采取直接忽略的策略,因此集合A和B做减法只是将集合A中也同时属于集合B的元素减掉。 MySQL 8.0 还不支持 表的减法运算符 EXCEPT. 不过, 借助第六章学过的NOT IN 谓词, 我们同样可以实现表的减法. 练习题**:** 找出只存在于product表但不存在于product2表的商品. -- 使用 IN 子句的实现方法 SELECT * FROM product WHERE product_id NOT IN (SELECT product_id FROM product2) 4.1.4.2 EXCEPT 与 NOT 谓词通过上述练习题的MySQL解法, 我们发现, 使用 NOT IN 谓词, 基本上可以实现和SQL标准语法中的EXCEPT运算相同的效果. 练习题: 使用NOT谓词进行集合的减法运算, 求出product表中, 售价高于2000,但利润低于30%的商品, 结果应该如下表所示. 参考答案: SELECT * FROM product WHERE sale_price > 2000 AND product_id NOT IN (SELECT product_id FROM product WHERE sale_price 1.5 * purchase_price AND sale_price < 1500 4.1.5对称差两个集合A,B的对称差是指那些仅属于A或仅属于B的元素构成的集合. 对称差也是个非常基础的运算, 例如, 两个集合的交就可以看作是两个集合的并去掉两个集合的对称差.上述方法在其他数据库里也可以用来简单地实现表或查询结果的对称差运算: 首先使用UNION求两个表的并集, 然后使用INTERSECT求两个表的交集, 然后用并集减去交集, 就得到了对称差. 但由于在MySQL 8.0 里, 由于两个表或查询结果的并不能直接求出来, 因此并不适合使用上述思路来求对称差. 好在还有差集运算可以使用. 从直观上就能看出来, 两个集合的对称差等于 A-B并上B-A, 因此实践中可以用这个思路来求对称差. 练习题: 使用product表和product2表的对称差来查询哪些商品只在其中一张表, 结果类似于: 提示: 使用 NOT IN 实现两个表的差集. 参考答案: -- 使用 NOT IN 实现两个表的差集 SELECT * FROM product WHERE product_id NOT IN (SELECT product_id FROM product2) UNION SELECT * FROM product2 WHERE product_id NOT IN (SELECT product_id FROM product) 4.1.5.1借助并集和差集迂回实现交集运算 INTERSECT通过观察集合运算的文氏图, 我们发现, 两个集合的交可以看作是两个集合的并去掉两个集合的对称差。
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |