700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > SQL进阶教程——自连接的用法(第二章)

SQL进阶教程——自连接的用法(第二章)

时间:2018-08-15 13:22:51

相关推荐

SQL进阶教程——自连接的用法(第二章)

1. 什么是自连接

针对相同的表进行的连接被称为“自连接”,一旦熟练掌握自连接技术,我们便能快速的解决很多问题。但是,其处理过程不太容易想象,以至于常常被人们敬而远之。

理解自连接不仅可以让我们学会实际工作中能用到的技能,还能增进我们对“面向集合”这一SQL语言特征的理解。

2. 可重排列,排列,组合

Products

假设这列有一张存放了商品名称及价格的表,表里有“苹果,橘子,香蕉”这三条记录。在生成用于查询销售额的报表等的时候,我们有时候需要获取这些商品的组合。

这里说的组合其实分为两种类型。一种是有顺序的有序对,另一种是无顺序的无序对。对应着学校里的术语“排列”和“组合”

--用于获取可重排列(有序对)的SQL语句SELECT P1.name AS name_1,P2.name AS name_2FROM Products P1,Products P2;--交叉连接生成笛卡尔积--用于获取排列的SQL语句SELECT P1.name AS name_1,P2.name AS name_2FROM Products P1,Products P2WHERE P1.name <> P2.name;--用于生成组合的SQL语句SELECT P1.name AS name_1,P2.name AS name_2FROM Products P1,Products P2WHERE P1.name > P2.name;

注意:

这里将非等值连接与自连接结合使用了,因此称为“非等值自连接”。在需要获取列的组合时,我们经常需要用到这个技术,请牢记。

3. 删除重复行

下面有一张商品表,现在假设在这张表里,“橘子”这种商品存在重复。可怕的是,这张表里连主键都没有(其实是根本无法设置主键)。我们需要马上清理一下,去掉重复行。

Products

--用于删除重复行的SQL语句(1):使用极值函数DELETE FROM Products P1WHERE rowid < (SELECT MAX(P2.rowid)FROM Products P2WHERE P1.name = P2.nameAND P1.price = P2.price);/**需要使用由数据库独自实现的行ID,这里的行ID可以理解成拥有“任何表都可以使用的主键”,这里使用的Oracle数据库里的rowid这个子查询会比较两个集合P1好P2,然后返回商品名称和价格都相同的行最大的rowid所在的行**/--用于删除重复行的SQL语句(2):使用非等值连接DELETE FROM Products P1WHERE EXISTS (SELECT *FROM Products P2WHERE P1.name = P2.nameAND P1.price = P2.priceAND P1.rowid < P2.rowid);

4. 查找局部不一致的列

Addresses

--查找是同一家人但住址去不同的记录SELECT DISTINCT A1.name,A1.addressFROM Addresses A1,Addresses A2WHERE A1.family_id = A2.family_idAND A1.address <> A2.address;--自连接和非等值连接

5. 排序

Products

现在我们要按照价格从高到低的顺序,对下面这张表的商品进行排序。

--排序:使用窗口函数SELECT name,priceRANK() OVER (ORDER BY price DESC) AS RANK_1,--会跳过位次DENSE_RANK() OVER(ORDER BY price DESC) AS RANK_2--不会跳过位次FROM Products;

--排序从1开始,如果已出现相同位次,则跳过之后的位次SELECT P1.name,P2.price,(SELECT COUNT(P2.price)FROM Products P2WHERE P2.price > p1.price) + 1 AS RANK_1--子查询所做的,是计算出价格比自己搞的记录的条数并将其作为自己的位次FROM Products P1GROUP BY RANK_1;/**这段代码很容易扩展。例如去掉标量子查询后边的+1,就可以从0开始排序,而且如果修改成COUNT(DISTINCT P2.price),那么存在相同位次的记录时,就可以不跳过之后的位次,而是连续输出(相当于DENSE_RANK函数)**/

再次强调,在关联子查询中是信息流是双向的。外部查询的每行数据传递一个值给子查询,然后子查询为每一行数据执行一次并返回它的记录。然后,外部查询根据返回的记录做出决策。

--排序:使用自连接SELECT P1.name,MAX(P1.price) AS price,COUNT(P2.name) +1 AS rank_1FROM Products P1 LEFT OUTER JOIN Products P2--这里如果使用内连接,那么第一名“橘子”就会消失,因为没有比橘子价格更高的水果ON P1.price < p2.priceGROUP BY P1.nameORDER BY rank_1;

本节要点:

自连接经常和非等值连接结合起来使用自连接和GROUP BY结合使用可以生成递归集合将自连接看做不同表之间的连接更容易理解应把表看做行的集合,用面向集合的方法来思考自连接的性能开销很大,应尽量给用于连接的列建立索引

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。