数据库学习笔记——13 创建高级联结

1 使用别名

SELECT CONCAT(vend_name,'(',vend_country,')') AS vend_title FROM vendors ORDER BY vend_name;
SQL除了可以对列名和计算字段使用别名,还允许给表名起别名。这样做有两个主要理由:

  • 缩短SQL语句;
  • 允许在一条SELECT语句中多次使用相同的表。
    SELECT cust_name,cust_contact FROM customers AS C, orders AS O,orderitems AS OI WHERE C.cust_id = O.cust_id AND OI.order_num = O.order_num AND prod_id = 'RGAN01'
    as.png

    表别名不仅能用于WHERE子句,还可以用于SELECT的列表、ORDER BY子句以及其他语句部分。
    注意:Oracle不支持AS关键字,直接指定别名即可。(例如:orders O)

2 使用不同类型的联结

除了内联结(inner join)之外,现在来看三种其他联结:自联结(self-join)、自然联结(natural join)和外联结(outer join)。

2.1 自联结

使用子查询:
SELECT cust_id,cust_name,cust_contact FROM customers WHERE cust_name = (SELECT cust_name FROM customers WHERE cust_contact = 'Jim Jones');
使用联结的相同查询:
SELECT c1.cust_id,c1.cust_name,c1.cust_contact FROM customers AS c1,customers AS c2 WHERE c1.cust_name = c2.cust_name AND c2.cust_contact = 'Jim Jones'

self_join.jpg

提示:使用自联结而不用子查询
DBMS处理联结远比处理子查询快得多。

2.2 自然联结

标准的联结(内联结)返回所有数据,相同的列甚至多次出现。自然联结排除多次出现,使每一列只返回一次。系统不会完成这项工作,只能自己完成。
自然联结要求只能选择那些唯一的列,一般通过对一个表使用通配符(SELECT *),而对其他表的列使用明确的子集来完成。
SELECT C.*,O.order_num,O.order_date,OI.prod_id,OI.quantity,OI.item_price FROM customers AS C, orders AS O, orderitems AS OI WHERE C.cust_id = O.cust_id AND OI.order_num = O.order_num AND prod_id = 'RGAN01';

natural_join.jpg

事实上,我们迄今为止建立的每个内联结都是自然联结,很可能永远都不会用到不是自然联结的内联结。

2.3 外联结

联结包含了那些在相关表中没有关联行的行。这种联结称为外联结。

先看一个简单的内联结:
SELECT customers.cust_id, orders.order_num FROM customers INNER JOIN orders ON customers.cust_id = orders.cust_id;

inner_join.jpg

外联结语法类似:检索包括没有订单顾客在内的所有顾客。
SELECT customers.cust_id,orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id ;

left_outer_join.jpg

与内联结关联两个表中的行不同的是,外联结还包括没有关联行的行。
在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表)。
SELECT customers.cust_id,orders.order_num FROM customers RIGHT OUTER JOIN orders ON customers.cust_id = orders.cust_id ;

right_outer_join.jpg

提示:外联结的类型
要记住,总是有两种基本的外联结形式:左外联结和右外联结。它们之间的唯一差别是所关联的表的顺序。换句话说,调整FROM或WHERE子句中表的顺序,左外联结可以转换为右外联结。因此,这两种外联结可以相互使用。

还存在另一种外联结,就是全外联结(full outer join),它检索两个表中的所有行并关联那些可以关联的行。与左外联结或右外联结包含一个表的不关联的行不同,全外联结包含两个表的不关联的行。
然而MySQL不支持这个语法,但是可以通过union来实现 :

SELECT customers.cust_id,orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id UNION SELECT customers.cust_id,orders.order_num FROM customers RIGHT OUTER JOIN orders ON customers.cust_id = orders.cust_id ;

union.jpg

3 使用带聚集函数的联结

0556A69C.jpg

例子:检索所有顾客及每个顾客所下的订单数。
SELECT customers.cust_id,COUNT(orders.order_num) AS num_ord FROM customers INNER JOIN orders ON customers.cust_id = orders.cust_id GROUP BY customers.cust_id;

聚集_join.jpg

例子:使用左外联结检索包含所有顾客及其对应的订单数(包含没有任何订单的顾客)
SELECT c.cust_id,COUNT(o.order_num) AS num_ord FROM customers c LEFT OUTER JOIN orders o ON c.cust_id = o.cust_id GROUP BY c.cust_id;

聚集函数_外联结.jpg

4 总结

  • 注意所使用的联结类型。一般我们使用内联结,但使用外联结也有效。
  • 注意使用正确的联结语法。
  • 保证使用正确的联结条件。
  • 必须给出联结条件,避免出现笛卡尔积。
  • 在一个联结中可以包含多个表,甚至可以对每个联结采用不同的联结类型。虽然这样做是合法的,一般也很有用,但是应该在一起测试它们前分别测试每个联结。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 这一篇最主要是记录下命令,方便以后查找 使用Mysql 创建数据库 create database mysql_t...
    Treehl阅读 571评论 0 0
  • 表 存储在表中的数据是同一种类型的数据或清单。 数据库中的表有为一个名字来标识自己。 表具有一些特性,这些特性定义...
    蛐蛐囍阅读 1,302评论 0 7
  • 注:这一系列的文章是《SQL必知必会》第四版的读书笔记。 7.创建计算字段 什么是计算字段,怎么创建计算字段,以及...
    zuyuxia阅读 326评论 0 0
  • 一、基本概念 数据库、表、列、行、主键、外键、关键字 二、检索 1.检索列 SELECT prod_name(id...
    兀镜晓Jingle阅读 341评论 0 7
  • 时境过迁。 三子废了很大的劲儿找到了小如给他的地址。他托人问了小小的圈子才算是问对了路。 这一带是旧城区,没有宽阔...
    酸画阅读 452评论 0 5