一、使用表别名


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';

分析▼

可以看到,FROM子句中的三个表全都有别名。Customers AS C使用C作为Customers的别名,如此等等。

这样,就可以使用省略的C而不用全 名Customers。在这个例子中,表别名只用于WHERE子句。

其实它不仅能用于WHERE子句,还可以用于SELECT的列表、ORDER BY子句以及其 他语句部分。

警告:

Oracle中没有AS Oracle不支持AS关键字。要在Oracle中使用别名,可以不用AS,简单地指定列名即可(因此,应该是Customers C,而不是Customers AS C)。

需要注意,表别名只在查询执行中使用。与列别名不一样,表别名不返回到客户端。

二、自联结


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';

提示:Oracle中没有AS Oracle用户应该记住去掉AS。

分析▼

此查询中需要的两个表实际上是相同的表,因此Customers表在FROM子句中出现了两次。虽然这是完全合法的,但对Customers的引用具有歧 义性,因为DBMS不知道你引用的是哪个Customers表。

解决此问题,需要使用表别名。Customers第一次出现用了别名C1,第二次出现用了别名C2。现在可以将这些别名用作表名。例如,SELECT语 句使用C1前缀明确给出所需列的全名。如果不这样,DBMS将返回错误,因为名为cust_id、cust_name、cust_contact的列各有两个。DBMS不 知道想要的是哪一列(即使它们其实是同一列)。WHERE首先联结两个表,然后按第二个表中的cust_contact过滤数据,返回所需的数据。

提示:

用自联结而不用子查询 自联结通常作为外部语句,用来替代从相同表中检索数据的使用子查询语句。虽然最终的结果是相同的,但许多DBMS处理联结远比处理子 查询快得多。

应该试一下两种方法,以确定哪一种的性能更好。

三、自然联结

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';

分析▼

在这个例子中,通配符只对第一个表使用。所有其他列明确列出,所以没有重复的列被检索出来。

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

四、外联结


SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders ON Customers.cust_id = Orders.cust_id;

分析▼

这条SELECT语句使用了关键字OUTER JOIN来指定联结类型(而不是在WHERE子句中指定)。

但是,与内联结关联 两个表中的行不同的是,外联结还包括没有关联行的行。

在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表 (RIGHT指出的是OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表)。

上面的例子使用LEFT OUTER JOIN从FROM子句左边的 表(Customers表)中选择所有行。为了从右边的表中选择所有行,需要使用RIGHT OUTER JOIN,

警告:

SQLite外联结 SQLite支持LEFT OUTER JOIN,但不支持RIGHT OUTER JOIN。

幸好,如果你确实需要在SQLite中使用RIGHT OUTER JOIN,有一种更简 单的办法,这将在下面的提示中介绍。

提示:外联结的类型 要记住,总是有两种基本的外联结形式:左外联结和右外联结。

它们之间的唯一差别是所关联的表的顺序。换句话说,调 整FROM或WHERE子句中表的顺序,左外联结可以转换为右外联结。

因此,这两种外联结可以互换使用,哪个方便就用哪个。

 全外联结(full outer join)

SELECT Customers.cust_id, Orders.order_num FROM Orders FULL OUTER JOIN Customers ON Orders.cust_id = Customers.cust_id;

警告:

FULL OUTER JOIN的支持 Access、MariaDB、MySQL、OpenOffice Base或SQLite不支持FULL OUTER JOIN语法。

五、使用带聚集函数的联结

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;
输出▼
cust_id um_ord
---------- --------
1000000001 2
1000000003 1
1000000004 1
1000000005 1

分析▼

这条SELECT语句使用INNER JOIN将Customers和Orders表互相关联。

GROUP BY子句按顾客分组数据,因此,函数调 用COUNT(Orders.order_num)对每个顾客的订单计数,将它作为num_ord返回。

六、使用联结和联结条件


  • 注意所使用的联结类型。一般我们使用内联结,但使用外联结也有效。
  • 关于确切的联结语法,应该查看具体的文档,看相应的DBMS支持何种语法(大多数DBMS使用这两课中描述的某种语法)。
  • 保证使用正确的联结条件(不管采用哪种语法),否则会返回不正确的数据。
  • 应该总是提供联结条件,否则会得出笛卡儿积。
  • 在一个联结中可以包含多个表,甚至可以对每个联结采用不同的联结类型。虽然这样做是合法的,一般也很有用,但应该在一起测试它们 前分别测试每个联结。这会使故障排除更为简单。

12.创建高级联结---SQL的更多相关文章

  1. SQL 必知必会·笔记<11>创建高级联结

    1. 使用表别名 SQL 除了可以对列名和计算字段使用别名,还允许给表名起别名.这样 做有两个主要理由: 缩短SQL 语句: 允许在一条SELECT 语句中多次使用相同的表. 使用表别名示例: SEL ...

  2. mysql必知必会-创建高级联结

    使用表别名 使用别名引用被检索的表列 别名除了用于列名和计算字段外,SQL还允许给表名起别名.这样做 有两个主要理由: 缩短SQL语句: 允许在单条 SELECT 语句中多次使用相同的表. 可以看到, ...

  3. 翻译:高级t - sql第1级的阶梯:使用交叉连接来引入高级t - sql

    高级t - sql第1级的阶梯:使用交叉连接来引入高级t - sql 源于:格雷戈里·拉森,2016/02/19(首次出版:2014/12/17 翻译:刘琼滨 谢雪妮 徐雅莉 赖慧芳 链接:http: ...

  4. 在腾讯云上创建您的SQL Cluster(3)

    版权声明:本文由李斯达原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/250 来源:腾云阁 https://www.qclo ...

  5. 批处理创建数据库(Sql Server)

    ylbtech-Miscellaneos:批处理创建数据库(Sql Server) 1.A,资源(Resource) - 创建数据返回顶部 1.A.1,InstallDatabases.cmd - 编 ...

  6. 使用面向对象技术创建高级 Web 应用程序

    作者: 出处: 使用面向对象技术创建高级 Web 应用程序 来源:开源中国社区 作者:oschina 最近,我面试了一位具有5年Web应用开发经验的软件开发人员.她有4年半的JavaScript编程经 ...

  7. phpmyadmin查看创建表的SQL语句

    本人菜鸟 发现创建表的SQL语句还不会 直接phpmyadmin解决的 查看见表的语句除了直接到处SQL格式文件 打开查看外 就是执行语句查询 语句:show create table 表名  貌似大 ...

  8. 在腾讯云上创建您的SQL Cluster(4)

    版权声明:本文由李斯达原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/255 来源:腾云阁 https://www.qclo ...

  9. php大力力 [023节]CREATE TABLE创建新表sql写字段备注(2015-08-27)

    2015-08-27 php大力力023.CREATE TABLE创建新表sql写字段备注 http://www.cnblogs.com/dalitongxue/p/4762182.html 参考: ...

随机推荐

  1. 如何让你的手机U盘集PE工具、系统安装、无线破解等众多功能于一身

    不久前,手里的U盘坏了,于是乎,又在网上淘了一个Type-C U盘,刚好手机电脑都可以用. 那么现在U有了,我们要做什么呢? 第一:让U盘插在手机上时,可以供手机读写,实现手机存储扩容,随插随用,简单 ...

  2. 使用jedisPool管理jedis,使用jedis操作redis

    ps:jedis是redis在java中的客户端操作工具 package com.test; 2 3 import java.util.HashMap; 4 import java.util.Iter ...

  3. Promise 入门与使用

    Tags: ECMAScript6 参考资料 promises-book Promise对象 we-have-a-problem-with-promises Promise最初被提出是在 E语言中, ...

  4. leetcode 307. Range Sum Query - Mutable(树状数组)

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  5. k8s-集群状态及部署一个实例

    [root@k8s-master ~]# kubectl get csNAME STATUS MESSAGE ERRORcontroller-manager Healthy ok scheduler ...

  6. ACM学习历程——HDU4814 Golden Radio Base(数学递推) (12年成都区域赛)

    Description Golden ratio base (GRB) is a non-integer positional numeral system that uses the golden ...

  7. bzoj3456城市规划 多项式取模

    題目大意 求出有n个点的有标号简单连通无向图的数目. 题解 什么破玩意,直接输出\(2^{C_n^2}\)走人 我们发现这张图要求连通,而上式肯定不能保证连通. 其实上式表示的是不保证连通的有标号简单 ...

  8. Mycat概述

    Mycat是什么?从定义和分类来看,它是一个开源的分布式数据库系统,是一个实现了MySQL协议的的Server,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用 ...

  9. Vijos1579:宿命的PSS

    背景 P.S.S:“我来自哪里?”WH:“你来自一个图.”P.S.S:“我是谁?”WH:“你是最小生成树.”P.S.S:“我又要到哪里去?”WH:“你要成为一个最小完全图(边权之和最小的完全图).”P ...

  10. POJ3264(线段树入门题)

    Balanced LineupCrawling in process... Crawling failed Time Limit:5000MS     Memory Limit:65536KB     ...