使用表别名目的:
- 缩短mysql语句
- 在单条select中重复使用表名
- 对表使用别名 貌似可以省略 as ,之前就是那样做的,不知道其他的dbms可不可以。
SELECT concat(vend_name,'(',vend_country,')') AS vend_title
FROM vendors v
ORDER BY vend_name ;
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 = 'TNT2';
自联结,from两个自己,可以不止一次引用相同的表/自己。
SELECT语句使用p1前缀明确地给出所需列的全名。
WHERE(通过匹配p1中的vend_id和p2中的vend_id)首先联结两个表,然后按第二个表中的prod_id过滤数据,返回所需的数据。
SELECT p1.prod_id ,p1.prod_name
FROM products p1,products p2
WHERE p1.vend_id = p2.vend_id
AND p2.prod_id = 'DTNTR';
-- 自联结,from 两个自己
外部联结:联结包含了那些在相关表中没有关联行的行。这种类型的联结称为外部联结
发现使用 inner join 有自动补全。
它检索所有客户及其订单,没有包括那些没有订单的客户。
SELECT c.cust_id ,o.order_num
FROM customers c INNER JOIN orders o
ON c.cust_id = o.cust_id ;
要想使用外部联结,包括那些没有订单的客户,可以这样:
SELECT c.cust_id ,o.order_num
FROM customers c LEFT OUTER JOIN orders o
ON c.cust_id = o.cust_id ;
可见 INNER JOIN 是内部联结,OUTER JOIN 是外部联结的关键字。
其中外部联结前面又有 LEFT 和 RIGHT 两个关键字。表示指定包括其所有行的表是FROM 左边的表还是右边的表。这里的 LEFT 表示的就是 c 表中的所有行。
其中返回的第三行,就表示cust_id 为10002的客户没有在orders表中没有过联结即没有订单。
使用带聚集函数的联结,从多个表汇总数据
group by 分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算(count()就是一种聚集计算)。
SELECT c.cust_name ,
c.cust_id ,
count(o.order_date) AS num_ord
-- num_ord 表示的是对于每一个 cust_id 的分组,计算在orders中的出现次数,这里参数可以填orders表中的任意字段
FROM customers c INNER JOIN orders o
ON c.cust_id = o.cust_id
GROUP BY c.cust_id ;
此SELECT语句使用INNER JOIN将customers和orders表互相关联。
GROUP BY 子句按客户分组数据,因此,函数调用 COUNT(orders.order_num)对每个客户的订单计数,将它作为num_ord返回。
结合外部联结,同时显示出没有订单的客户资料:
SELECT c.cust_name ,
c.cust_id ,
count(o.order_date) AS num_ord
-- num_ord 表示的是对于每一个 cust_id 的分组,计算在orders中的出现次数,这里参数可以填orders表中的任意字段
FROM customers c LEFT OUTER JOIN orders o
ON c.cust_id = o.cust_id
GROUP BY c.cust_id ;
总结:
- 知道使用表别名,在单挑select语句中重复引用相同的表
- 外部联结可以显示那些在相关表中没有关联行的行。通过 LEFT/RIGHT outer join 实现
- 利用分组和聚集函数和联结,从多个表获取数据,通过 group by 分组,inner join 联结或外部联结,聚集函数实现。
- 内联结,两边表同时有对应的数据,即任何一边缺失数据就不显示。
- 左联结,读取左边数据表的全部数据,即便右边表无对应数也会默认显示NULL。