SQL 学习:十
联结表:指定要联结的所有表以及关联它们的方式即可。
SELECT vend_name,prod_name,prod_price FROM Vendors,Products WHERE Vendors.vend_id=Products.vend_id;
目前为止使用的联结称为等值联结(equijoin),它基于两个表之间的相等测试。这种联结也成为内联结。
挑战1:返回Customers表中的顾客名称(cust_name)、Orders表中的相关订单号(Order_num)以及第三列OrderTotal(包含每个订单的总价),并按照顾客名称再按订单号对结果进行排序。
SELECT cust_name,order_num,(
SELECT SUM(quantity*item_price) FROM OrderItems WHERE OrderItems.order_num=Orders.order_num)AS OrderTotal
FROM Customers,Orders WHERE Customers.cust_id=Orders.cust_id ORDER BY cust_name, order_num;
---第二种方式
SELECT cust_name,
Orders.order_num,
Sum(item_price*quantity) AS OrderTotal
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND Orders.order_num = OrderItems.order_num
GROUP BY cust_name, Orders.order_num
ORDER BY cust_name, order_num;
表别名只再查询执行中使用。与列别名不一样,表别名不返回到客户端。
使用表别名的一个主要原因是能在一条SELECT语句中不止一次引用相同的表。
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';
SELECT cust_id,cust_name,cust_contact FROM Customers WHERE cust_name=(
SELECT cust_name FROM Customers WHERE cust_contact='Jim Jones'
);
此查询中需要的两个表实际上是相同的表,因此相同的表出现了两次。虽然是合法的,但是再DBMS中具有歧义性(在返回的时候存在错误,DBMS不知到哪个是第一列虽然他们相同)。因此使用表别名。
内联结:关联相关联的行,使用INNER JOIN
外联结:还包括没有关联的行,使用OUTER JOIN
都不是在WHERE子句中指定。
外联结在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT指出的是右边的表,LEFT指出的是左边的表。FROM/where子句中输入的表的顺序判断)
外联结的类型:左边联结和右边联结。它们之间的唯一差别是所关联的表的顺序。
---左边的表
SELECT Customers.cust_id,Orders.order_num FROM Customers LEFT OUTER JOIN Orders ON Customers.cust_id=Orders.cust_id;
---右边的表
SELECT Customers.cust_id,Orders.order_num FROM Customers RIGHT OUTER JOIN Orders ON Customers.cust_id=Orders.cust_id;
全外联结:检索两个表中的所有行并关联那些可以关联的行,包含两个表的不关联的行。
SELECT Customers.cust_id,Orders.order_num FROM Customers FULL OUTER JOIN Orders ON Customers.cust_id=Orders.cust_id;
语法
内联结:INNER JOIN...ON
外联结:RIGHT/LEFT OUTER JOIN..ON
全外联结:FULL OUTER JOIN..ON
---聚集函数的联结
SELECT Customers.cust_id,COUNT(Orders.order_num) AS num_old FROM Customers INNER JOIN Orders ON Customers.cust_id=Orders.cust_id GROUP BY Customers.cust_id;
以cust_id分组计数order_num作为num_old返回。