leftjoinon参数走索引 left join on 索引_sql left join用法


最近一直在想做关于SQL的应用案例,这周刚好看到Github上关于天池算法大赛上,菜鸟需求预测与分仓分析,看了【队名:左手诗句,右手数据】排名第一的数据处理过程,受益良多,想着把自己的拆解过程写下来,供初学者一起参考学习。

这个sql有340行,26KB。有兴趣的同学可以在我的文章《菜鸟需要与分仓分析SQL语句》中进行查看。


leftjoinon参数走索引 left join on 索引_sql left join用法_02


表1:标签


leftjoinon参数走索引 left join on 索引_sql left join on 多条件_03


我们先捋一下整个SQL的结构,其中left outer join为表与表的连接语句,把表分成以下几个部分。

表2-15:最近1天--最近14天


leftjoinon参数走索引 left join on 索引_sql left join on 多条件_04


表16:item_id为首列,非聚划算的最大,最小,标准差。


leftjoinon参数走索引 left join on 索引_sql left join 去重_05


表17:item_id为首列,连接起以下各个类型特征


leftjoinon参数走索引 left join on 索引_sql left join用法_06


表18:叶子类特征


leftjoinon参数走索引 left join on 索引_sql left join 去重_07


表19:大类目特征


leftjoinon参数走索引 left join on 索引_leftjoinon参数走索引_08


表20:品牌特征


leftjoinon参数走索引 left join on 索引_sql left join 去重_09


表21:供应商ID特征


leftjoinon参数走索引 left join on 索引_leftjoinon参数走索引_10


特别要说的是表21最后这个 k on(a.item_id=k.item_id),连接起了表17到表21,非常重要。

总结:

一:由于我用pandas较多,从没想过mysql还能这么用,mysql在构建特征时,很高效,我曾想着用pandas 也能做,当然,我试了,是可以,同样对一item_id进行groupby后,使用agg复合函数,就像这样:

比如调用day_1的数据:


leftjoinon参数走索引 left join on 索引_sql left join 去重_11


leftjoinon参数走索引 left join on 索引_leftjoinon参数走索引_12


我们能看到,即使有agg的复合函数,虽然同样能实现这样的功能要求,但在列的命名上,不够灵活。如果每次执行的列名都是变化的,比如这里,反复的对列进行sum(),mean(),还要求列名重命名,即使可以使用(lambda:x+"_1" for x in columns)但调用14次,但也是非常低效的,而mysql一句 select sum(pv_uv)as pv_uv_sum,非常灵活。

二:另外一点,对两个表以上的聚合,merge,concat有了更深的理解,比如这里


leftjoinon参数走索引 left join on 索引_sql left join用法_13


pd.concat()可以对多个dateframe进行聚合,但它只能选择对axis=0或者axis=1 也就是按列或者按行,进行聚合。


pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
       keys=None, levels=None, names=None, verify_integrity=False)


参数说明
objs: series,dataframe或者是panel构成的序列lsit
axis:需要合并链接的轴,0是行,1是列
join:连接的方式 inner,或者outer

它没有可以选择聚合的关键连接列,即缺少on这个关键列。

而pd.merge(),是可以选择聚合的关键连接列


pd.merge(left, right, how=’inner’, on=None, left_on=None, 
right_on=None, left_index=False, right_index=False, sort=False,
 suffixes=(‘_x’, ‘_y’), copy=True, indicator=False, validate=None)


所以,结论是,如果两个表的结构相同,而且是只想做上下的叠加,或者左右的叠加,对index列没有要求删除,那么可以用concat,但如果是两个表之间的join,用pd.merge()。