SELECT * FROM orders o,customer c WHERE o.customerid=c.customerid; SELECT * FROM orders o JOIN customer c ON o.customerid=c.customerid; SELECT * FROM orders o INNER JOIN customer c ON o.customerid=c.customerid;
以上三种都属于内连接
目录
外连接与视图
外连接 - 左连接、右连接
我们来看这种场景:
-
有两张表如下:
-
首先我们来看内连接的情况
内连接只会将有购买数据的客户的信息查询出来
-
那如果我们需要查询所有客户的购买额度呢?
此时我们就要用到外连接
也就是需要可以达到这种效果
-
然后保留自己想要的数据
因此如果对应这种需求我们就需要使用外连接,因为内连接是无法查询出没有购买数据的客户的,所以就有外连接
book数据库之外连接
customer 表有 1375 条数据
orders 表有 7999 条数据
左连接
统计每个客户的购买金额
-
要想知道每个客户,那我们就要以 customer 表中的 customerid 作为主要依赖,以此表作为左表进行左连接
-
使用关键字
LEFT JOIN ON
-
注意:orders 表中的 custoerid 有很多是重复的,因为一个客户可能会有很多订单
-
我们在编写sql查询语句的时候,如果使用到了 GROUP BY 我们一定要使用聚合函数来做一些有意义的事,并不是说使用 GROUP BY 的时候不使用聚合函数就是错的,而是这样的话做的就是无意义的行为,因为这无非就是和 DISTINCT 的作用是一样的
-
使用 GROUP BY 时,我们可以计算 SUM AVG COUNT MAX MIN
-
如果不计算聚合函数那么使用 GROUP BY 就失去了意义,还不如直接 DISTINCT
-
-
还有就是在进行外连接的时候,如果要使用 GROUP BY 一定要注意 GROUP BY 的对象
-
就拿下面这个题举例子,如果是
GROUP BY o.customerid
结果就是错的。因为在 orders 表中的客户有很多不存在于 customer 表中,导致 customer 表作为左表连接了之后,右表 orders 中对应的customerid 就有很多空值,如果此时对 o.customerid 进行 GROUP BY 就会导致这些所有客户全都变成了一条数据,就错了
-
SELECT * FROM customer c LEFT JOIN orders o ON c.customerid=o.customerid GROUP BY c.customerid; SELECT c.customerid,c.name,SUM(money) FROM customer c LEFT JOIN orders o ON c.xustomerid=o.customerid GROUP BY c.customerid; SELECT c.customerid,c.name,IF(SUM(money) IS NULL,0,SUM(money)) FROM customer c LEFT JOIN orders o ON c.customerid=o.customerid GROUP BY c.customerid;
-
最终结果(1375条数据)
右连接
-
以右表为基准
-
实际上左连接和右连接没有实际上的区别,只不过是表的位置顺序和依赖的表不同了而已
-
左连接,依赖左表,可以将 customer 表放左边;右连接,依赖右表,可以将 customer 表放右边。所以这不是一样的吗
-
SELECT * FROM customer c LEFT JOIN orders o ON c.customerid=o.customerid GROUP BY c.customerid; 等同于 SELECT * FROM orders o RIGHT JOIN customer c ON c.customerid=o.customerid GROUP BY c.customerid;
当然,不同的连接方式可定是会有区别的
SELECT c.customerid,c.name,SUM(money) FROM customer c RIGHT JOIN orders o ON c.customerid=o.customerid GROUP BY c.customerid; 这条查询语句的结果就只有1190条数据,因为此时以 orders 表为基准,此时用 customer 表去匹配 orders 表。所以没有购买过书的客户的 customerid 就不会出现,因此最后虽然对 c.customerid 进行分组,但事实上却是对 orders 表中的customerid进行了分组
看,根本不会有金额为0的客户出现
所以我们在使用左右连接时一定要注意需求对应的表的顺序和依赖的主次关系
视图
-
将某些sql语句的查询结果永久保存在类似于表的结构中,可以非常方便的把一些复杂的sql语句和业务逻辑封装起来
对于一些有意义的查询,sql查询语句较为复杂,可以将其创建为视图
使用关键字 CREAT VIEM ... AS
CREAT VIEM customer_money AS SELECT c.customerid,c.name,IF(SUM(money) IS NULL,0,SUM(money)) total FROM customer c LEFT JOIN orders o ON c.customerid=o.customerid GROUP BY c.customerid;
-
有了视图之后,我们就可以把它当做表一样进行查询
SELECT * FROM customer_money WHERE total > 1000;
-
视图的本质其实和子查询,也就是临时表差不多
-
如果有一天表的结构发生变化,如果是写在视图中,则只需要修改视图一个地方就行
-
针对视图,也可以做删除,修改,插入的操作,会对应物理表的列进行相应操作,但是,不建议这样做。非查询类语句,一般不要议直接对视图操作