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)在一个联结中可以包含多个表,甚至可以对每个联结采用不同的联结类型,但是应该在一起测试它们之前分别测试每个联结。

  • 相关阅读:
    HDU 1874 畅通工程续(dijkstra)
    HDU 2112 HDU Today (map函数,dijkstra最短路径)
    HDU 2680 Choose the best route(dijkstra)
    HDU 2066 一个人的旅行(最短路径,dijkstra)
    关于测评机,编译器,我有些话想说
    测评机的优化问题 时间控制
    CF Round410 D. Mike and distribution
    数字三角形2 (取模)
    CF Round410 C. Mike and gcd problem
    CF Round 423 D. High Load 星图(最优最简构建)
  • 原文地址:https://www.cnblogs.com/Sumomo0516/p/6131547.html
Copyright © 2011-2022 走看看