• 这些年写过的花式sql 第2句 统计用户返佣金排名


    第2句 统计用户返佣金排名

    继续欢迎批评指正建议 ^^

    需求:

    曾经的活动是购买订单返流量(日志在 flow_rebate_log),后来改成返佣金(日志在 money_rebate_log)。
    现在需要 按照用户返佣金额排名,如果不存在金额,则按 返流量 排名。其他需要列出的字段:username(用户名 连接 users表获得),用户返佣金额,用户返佣金的订单数,用户返流量数,用户返流量的订单数

    SELECT r.*,u.username,
           flow_order_num + money_order_num as order_num,flow_order_money + money_order_money as order_money
    from
            (
                (
    							SELECT f.uid,rebate_flow,flow_order_num,rebate_money,money_order_num,f.money as flow_order_money,m.money as money_order_money
    								from
    									(SELECT sum(rebate_value) as rebate_flow,count(*) as flow_order_num,uid,money FROM `flow_rebate_log` group by uid) f
    									left join
    									(SELECT sum(consume_money) as rebate_money,count(*) as money_order_num,uid,money FROM `money_rebate_log` group by uid) m 
    									on m.uid = f.uid
    						)
    								
    						union
    
    						(
    							SELECT m.uid,rebate_flow,flow_order_num,rebate_money,money_order_num,f.money as flow_order_money,m.money as money_order_money
    							from
    									(SELECT sum(rebate_value) as rebate_flow,count(*) as flow_order_num,uid,money FROM `flow_rebate_log`  group by uid ) f  
    									right join
    									(SELECT sum(consume_money) as rebate_money,count(*) as money_order_num,uid,money FROM `money_rebate_log`  group by uid) m 
    									on m.uid = f.uid
    						)
            ) r
    
    left join 
    `users` u
    on u.id = r.uid
    

    排序在php代码里,因为想利用 TP框架的分页功能返回给前端。

    //$tb = "sql语句";
     $list = Db::table("($tb) t")
            ->order('rebate_money desc,rebate_value desc')
            ->limit(50)
            ->select();
    
    解析:

    因为有的用户 只出现在 flow_rebate_log,有的只出现在 money_rebate_log, 需要一个全连接。使得每条记录 同时 包含用户的返流量和返金额信息。 而mysql不支持full join,
    只能用一个trick : m (money_rebate_log ) full join f(flow_rebate_log) 相当于

    m left join f
    union
    m right join f
    

    由于 f.uid 和 m.uid 连接后 可能会有一个值是空的,那我们要取 肯定有值的。所以先选取 有效列 再 union。
    值得注意的是 union 和 union all 是有一点区别的,union 是去重的,union all是全部保留的。这里 每个用户只对应一条记录。所以 union 就可以了。

    知识点:

    模拟“full join” 和 union

  • 相关阅读:
    20年的 .NET ,更需要 00 后的你
    GNSS、RTK、基站、移动站
    Android系统定制之监听USB键盘来判断是否弹出软键盘
    问:未来5年的IT互联网行业,就业形势会是什么样的?
    在Linux上实现ECAT主站
    解决linux安装jarsigner失败
    探索图像分割技术:使用 OpenCV 的分水岭算法
    8Manage:电子寻源采购管理指南
    TCP协议
    【凸优化学习笔记1】什么是优化、优化的数学表达形式
  • 原文地址:https://www.cnblogs.com/xjcyue/p/17604104.html