MICK-SQL进阶教程 1.2 自连接的用法

针对相同的表进行的连接被称为“自连接”(self join)。一旦熟练掌握自连接技术, 我们便能快速地解决很多问题。

可重排列、排列、组合

-- 现有张表Products,内有一列name包含3个元素:苹果、橘子、香蕉

-- 生成有序对(笛卡尔乘积)
SELECT P1.name AS name_1, P2.name AS name_2
FROM Products P1, Products P2;
-- 答案:(苹果,苹果),(苹果,橘子),(苹果,香蕉);
--          (橘子,苹果),(橘子,橘子),(橘子,香蕉);
--          (香蕉,苹果),(香蕉,橘子),(香蕉,香蕉);

-- 排除掉由相同元素构成的对
SELECT P1.name AS name_1, P2.name AS name_2
FROM Products P1, Products P2 
WHERE P1.name <> P2.name;
-- 答案:(苹果,橘子),(苹果,香蕉);
--          (橘子,苹果),(橘子,香蕉);
--          (香蕉,苹果),(香蕉,橘子);

-- 用于获取组合的 SQL 语句
SELECT P1.name AS name_1, P2.name AS name_2
FROM Products P1, Products P2 
WHERE P1.name > P2.name;
-- 答案:(苹果,橘子);
--          (香蕉,橘子);
--          (香蕉,苹果);
-- 原理:这条 SQL 语句所做的是,按字符顺序排列各商品,只与“字符顺序比自己靠前”的商品进行配对。
-- 到这里,我们终于得到了无序对。

-- 想要获取 3 个以上元素的组合时,像下面这样简单地扩展一下就可以
SELECT P1.name AS name_1, P2.name AS name_2, P3.name AS name_3
FROM Products P1, Products P2, Products P3 
WHERE P1.name > P2.name AND P2.name > P3.name;
-- 答案:(香蕉,苹果,橘子);

  • 如这道例题所示,使用等号“=”以外的比较运算符,如“<、>、<>” 进行的连接称为“非等值连接”。这里将非等值连接与自连接结合使用了,因此称为“非等值自连接”。

删除重复行

重复行有多少行都没有关系。通常,如果重复的列里不包含主键,就可以用主键来处理,但像这道例题一样所有的列都重复的情况,则需要使用由数据库独自实现的行 ID。这里的行 ID 可以理解成拥有“任何表都可以使用的主键”这种特征的虚拟列。

-- 用于删除重复行的 SQL 语句 (1) :使用极值函数
-- 在下面的 SQL 语句里,我们使用的是 Oracle 数据库里的 rowid
delete from products p1
where rowid < (select max(p2.rowid)
               from products p2
               where p1.name = p2.name and p1.price = p2.price);

-- 用于删除重复行的 SQL 语句 (2) :使用非等值连接
DELETE FROM Products P1
WHERE EXISTS ( SELECT *
                             FROM Products P2
                             WHERE P1.name = P2.name
                                         AND P1.price = P2.price 
                         AND P1.rowid < P2.rowid )

查找局部不一致的列

-- 用于查找是同一家人但住址却不同的记录的 SQL 语句 
SELECT DISTINCT A1.name, A1.address
FROM Addresses A1, Addresses A2 
WHERE A1.family_id = A2.family_id 
          AND A1.address <> A2.address ;

排序

-- 排序 :使用窗口函数 
-- 在出现相同位次后,rank_1 跳过了之后的位次,rank_2 没有跳过, 而是连续排序。
SELECT name
             , price
             , RANK() OVER (ORDER BY price DESC) AS rank_1
             , DENSE_RANK() OVER (ORDER BY price DESC) AS rank_2 
FROM Products;

-- 不依赖于具体数据库来实现的方法。下面是用非等值自连接
SELECT P1.name
             , P1.price
             , (SELECT COUNT(P2.price)
                    FROM Products P2
          WHERE P2.price > P1.price) + 1 AS rank_1
FROM Products P1 ORDER BY rank_1;

本节要点

  1. 自连接经常和非等值连接结合起来使用。
  2. 自连接和GROUP BY结合使用可以生成递归集合。
  3. 将自连接看作不同表之间的连接更容易理解。
  4. 应把表看作行的集合,用面向集合的方法来思考。
  5. 自连接的性能开销更大,应尽量给用于连接的列建立索引。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • 笔记中所有的练习均使用MYSQL数据库 数据表的创建和管理 创建数据表 定义非空约束 定义默认值为字段设置一个默认...
    我不傻_cyy阅读 405评论 0 0
  • MySQL技术内幕:SQL编程 姜承尧 第1章 SQL编程 >> B是由MySQL创始人之一Monty分支的一个版...
    沉默剑士阅读 2,396评论 0 3
  • 关系型数据库和SQL SQL语言的三个部分DML:Data Manipulation Language,数据操纵语...
    Awey阅读 1,935评论 0 13
  • 数据库的基本是概念名词解释: 数据库名词解释 元组:可以理解为表的每一行就是一个元组 候选码:若关系中的某一属性组...
    杰伦哎呦哎呦阅读 1,097评论 0 6
  • 比我大两岁的姐姐,与我同级。现已都高三。 从小,她就因家境优裕而接受着高等教育。琴棋书画样样精通,成绩一流,活泼大...
    懒莹阅读 194评论 0 0