由于LEFT JOIN错误使用导致的数据不一致问题

msyql语句执行顺序
代码的执行顺序:
from... where...group by... having.... select ... order by...
hive 语句执行顺序
大致顺序
from... where.... select...group by... having ... order by...

LEFT JOIN有一个作用就是用于去除表A中表B的数据,现在我们来用几个示例来分析SQL执行顺序问题,以Hive为例:

错误示例一
SELECT * FROM(
SELECT rr.datekey,
               A.goods_id,
               B.poi_id B_poi_id               
          FROM A
          LEFT JOIN B
            ON A.poi_id = B.poi_id 
            WHERE A.datekey=20170403 AND B.datekey = 20170403) rs
         WHERE rs.B_poi_id IS NULL;

分析:此时先 ON LEFT JOIN 关联A B表,此时再用WHERE 选取了A.datekey=20170403并且B.datekey = 20170403的行,所以不会存在rs.B_poi_id IS NULL 的行了。

错误示例二:
SELECT rr.datekey,
               A.goods_id,
               B.poi_id B_poi_id               
          FROM A
          LEFT JOIN B
            ON A.poi_id = B.poi_id 
            WHERE A.datekey=20170403 AND B.datekey = 20170403 AND B.poi_id IS NULL

分析:这个也是属于逻辑混乱的,同上,在 ON LEFT JOIN后WHERE选取了A.datekey=20170403 AND B.datekey = 20170403 AND B.poi_id IS NULL 同时成立的行,这种就是不可能存在的,同一行不会B.datekey = 20170403 AND B.poi_id IS NULL成立。

错误示例三:
SELECT rr.datekey,
               A.goods_id,
               B.poi_id B_poi_id               
          FROM A
          LEFT JOIN B
            ON A.poi_id = B.poi_id AND A.datekey=20170403 AND B.datekey = 20170403 
            WHERE B.poi_id IS NULL

分析:这种presto和hive都跑不出来数据,最后job fail。

正确示例一:
SELECT rr.datekey,
               A.goods_id,
               B.poi_id B_poi_id               
          FROM A
          LEFT JOIN B2
          (SELECT B.poi_id 
          FROM B
          WHERE B.datekey = 20170403)AS B2
            ON A.poi_id = B2.poi_id
            WHERE A.datekey=20170403 AND B2.poi_id IS NULL

分析:通过子查询先查出B中这一天的数据,A再和B2 LEFT JOIN,最后选取A.datekey 和 B2.poi_id IS NULL 的行,正确。

正确示例二:
SELECT rr.datekey,
               A.goods_id,
               B.poi_id B_poi_id               
          FROM A
          LEFT JOIN B
            ON A.poi_id = B.poi_id  AND B.datekey = 20170403
            WHERE A.datekey=20170403 AND B.poi_id IS NULL

分析:这个其实就是上面的简化版,因为在ON里面先过滤了就是和上面的子查询是一样的道理。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值