zoukankan      html  css  js  c++  java
  • 13 创建高级联结

    1.使用表别名

    给列起别名的语法如下(第7章),输入:

    SELECT Concat(vend_name, ' (', RTRIM(vend_country), ')')

    FROM Vendors

    ORDER BY vend_name;

    输出:

    SQL除了可以对列名和计算字段使用别名,还允许给表名起别名。理由是:

    缩短SQL语句;

    允许在一条SELECT语句中多次使用相同的表。

    对前一课的例子:

    SELECT cust_name, cust_contact

    FROM Customers, Orders, OrderItems

    WHERE Customers.cust_id = Orders.cust_id

    AND OrderItems.order_num = Orders.order_num

    AND prod_id= 'RGAN01';

    改为使用别名,输入:

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

    输出:

    此例中表别名值用于WHERE子句,其实还可以用于SELECT的列表、ORDER BY子句以及其他语句部分。表别名只在查询执行中使用,不返回到客户端。

    2.使用不同类型的联结

    除了内联结或等值联结的简单联结,有三种其他联结:自联结(self_join)、自然联结(natural join)和外联结(outer join)

    (1)自联结

    假设要给与Jim Jones同一公司的所有顾客发送一封信件,该查询要求首先找出Jim Jones所在公司,然后找出在该公司的所有顾客。

    第一种解决方案,使用子查询,输入:

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

    输出:

    此查询中需要的两个表实际是相同的,因此Customers表在FROM子句中出现了两次,对Customers的引用具有歧义性,因为DBMS不知道引用的是哪个Customers表。表别名可以解决该问题。注意,SELECT语句使用c1前缀明确给出所需列的全面,否则,DBMS将返回错误。

    (2)自然联结

    标准联结(内联结)返回所有的数据,相同的列甚至多次出现,而自然联结排除多次出现,使每一列只返回一次。

    自然联结要求只能选择那些唯一的列,一般通过对一个表使用通配符(SELECT(*)),而对于其他表的列使用明确的子集来完成。

    输入:

    SELECT C.*, O.order_num, O.order_date

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

    输出:

    列出了订购物品'RGAN01'的所有顾客及其信息。

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

    (3)外联结

    外联结包含了那些在相关表中没有关联行的行,例如:

    1)对每个顾客下的订单进行计数,包括哪些至今尚未下订单的顾客;

    2)列出所有产品以及订购数量,包括没有人订购的产品;

    3)计算平均销售规模,包括哪些至今尚未下订单的顾客。

    下面是一个简单的内联结,检索所有顾客及其订单,输入:

    SELECT Customers.cust_id, Orders.order_num

    FROM Customers INNER JOIN Orders

    ON Customers.cust_id = Orders.cust_id;

    输出:

    外联结语法类似,要检索包括没有订单顾客在内的所有顾客,输入:

    SELECT Customers.cust_id, Orders.order_num

    FROM Customers LEFT OUTER JOIN Orders

    ON Customers.cust_id = Orders.cust_id;

    输出:

    SQL语句使用了关键字OUTER JOIN来指定连接类型,而不是在WHERE子句中指定。但必须用LEFTRIGHT关键字指定包括其所有行的表,RIGHT指的是OUTER JOIN右边的表,LEFT指的是左边的表。

    为了从右边的表选择所有行,输入:

    SELECT Customers.cust_id, Orders.order_num

    FROM Customers RIGHT OUTER JOIN Orders

    ON Customers.cust_id = Orders.cust_id;

    输出:

    另一种外联结——全外联结(full outer join),它检索两个表中的所有行并关联那些可以关联的行。全外联结包含两个表的不关联行。语法如下。

    输入:

    SELECT Customers.cust_id, Orders.order_num

    FROM Customers FULL OUTER JOIN Orders

    ON Customers.cust_id = Orders.cust_id;

    输出:MySQL不支持FULL OUTER JOIN语法。

    3.使用带聚集函数的联结

    聚集函数除了从一个表汇总数据,也可以与联结一起使用。

    假设要检索所有顾客即每个顾客下的订单数,使用COUNT()函数来完成,输入:

    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;

    输出:

    SELECT语句使用INNER JOINCustomersOrders表互相关联,GROUP BY子句按顾客分组分组数据,因此函数调用Count(Orders.order_num)对内个顾客的订单技术,将其作为num_ord返回。

    聚集函数也可以与其他联结一起使用,输入:

    SELECT Customers.cust_id,

    Count(Orders.order_num) AS num_ord

    FROM Customers LEFT OUTER JOIN Orders

    ON Customers.cust_id = Orders.cust_id

    GROUP BY Customers.cust_id;

    输出:

    使用左外部联结来包含所有顾客,甚至那些没有任何订单的顾客。如1000000002顾客,他有0个订单。

    4.使用联结和联结条件

    (1)注意所使用的联结类型,一般使用内联结,但使用外联结也有效。

    (2)应该查看具体文档获得确切的联结语法。

    (3)保证使用正确的联结语法,否则会返回不正确的数据。

    (4)应该总是提供联结条件,否则会得出笛卡尔积。

    (5)在一个联结中可以包含多个表,甚至可以对每个联结采用不同的联结类型,但是应该在一起测试它们之前分别测试每个联结。

  • 相关阅读:
    spring mvc注入配置文件里的属性
    spring mvc注入配置文件里的属性
    spring mvc注入配置文件里的属性
    ajaxFileUpload进行文件上传时,总是进入error
    ajaxFileUpload进行文件上传时,总是进入error
    ajaxFileUpload进行文件上传时,总是进入error
    配置quartz启动时就执行一次
    配置quartz启动时就执行一次
    JAVA遍历机制的性能的比较
    MyBatis中jdbcType与javaType对应表
  • 原文地址:https://www.cnblogs.com/Sumomo0516/p/6131547.html
Copyright © 2011-2022 走看看