关于左右连接碰到的问题

问题描述:

表1:日历表
表2:订单表
需求:本个月内每天的订单量及订单总金额

刚开始写法如下:

SELECT 
pd.datetime,
IFNULL(count(po.order_no),0) AS weekOrderCount,
IFNULL(sum(po.pay_money),0) AS weekMoneyAmount
FROM 
order po 
RIGHT JOIN datetime pd ON DATE_FORMAT(po.create_date, '%Y-%m-%d') = pd.datetime 
WHERE 
    order_status = 1
    AND pay_way_code = '01'
    AND shop_no = '1533817684573' 
    AND pd.datetime BETWEEN '2018-09-25' AND '2018-10-09' 
GROUP BY
    pd.datetime 
LIMIT 15;

此处发现结果并不是想象的样子存在每天的记录,此处当订单表没有当天的记录的时候在查询结果中并不会存在着记录,于是就感觉很奇怪,为什么以日期表为主表,当辅表不存在记录时主表记录并没有填充为NULL,而是直接被过滤掉了,后来多方了解,原因如下:
虽然定义中给出的左连接是显示主表的内容,可是如果有where条件,是要以where条件为主删选结果的,所以,以主表日期表为主表的记录同样也被过滤掉了,所以辅表的条件需要单独拿出来先进行筛选,正确写法如下:

SELECT 
pd.datetime,
IFNULL(count(po.order_no),0) AS weekOrderCount,
IFNULL(sum(po.pay_money),0) AS weekMoneyAmount
FROM 
(
    SELECT order_no,pay_money,create_date FROM order 
    WHERE 
    order_status = 1
    AND pay_way_code = 'xx'
    AND shop_no = 'xxxxxxxxxx' 
    AND DATE_FORMAT(create_date, '%Y-%m-%d') BETWEEN '2018-09-25' AND '2018-10-09' 
) po 
RIGHT JOIN datetime pd ON DATE_FORMAT(po.create_date, '%Y-%m-%d') = pd.datetime 
WHERE pd.datetime BETWEEN '2018-09-25' AND '2018-10-09' 
GROUP BY
pd.datetime 
LIMIT 15;

此处,子查询里也加入了时间限定,作用为提高查询效率,当然只需要最外部的时间限定就可以查询到正确的数据,此处去掉的话,首先会查询所有满足条件的记录,其查询结果远远多于我们需要的数据。

؏؏☝ᖗ乛◡乛ᖘ☝؏؏
谢谢关注。。

你可能感兴趣的:(关于左右连接碰到的问题)