业务前提:用户下单,订单归属于指定销售,审核通过的订单可以参与计算业绩。
需求描述:统计向,统计销售成单情况,要求显示指定销售人员最近审核通过的订单。
解决方案:暂列举3种,各有利弊,权衡取舍。
方案1:按需要GROUP BY的关键字段简单查询出全部数据,然后在程序中再次过滤、倒叙、取首。
局限性:批量查询时,数据量不可控,范围越大,内存越可能扛不住,单次查询结果量可预估时酌情考虑,不确定的话不推荐。
方案2:子查询的ORDER BY配合LIMIT使用。
局限性:对数据量有预估要求(本需求中要求覆盖user_order全表数据,不适用,未选择该方案)。
核心SQL如下:
SELECT
temp.sale_asset_id,
temp.last_passed_order_id,
temp.last_passed_order_create_time
FROM
(
SELECT
check.auth_user_id,
uo.id last_passed_order_id,
uo.create_time last_passed_order_create_time
FROM
user_order uo
INNER JOIN user_order_check check ON check.order_id = uo.id AND check.id = uo.sale_qc_check_id
WHERE
check.check_status = 200
AND check.auth_user_id IN (1,2,3)
ORDER BY
check.auth_user_id,
check.check_time DESC,
uo.id DESC
LIMIT 99999999
) temp
GROUP BY
temp.auth_user_id;
方案3:使用MAX函数针对倒叙条件“审核时间”取最大值,模拟倒叙。
局限性:需要对可能导致查询结果中GROUP BY字段数据非唯一的情况做考虑(本需求要求查询结果中销售数据唯一,影响唯一的字段是check_time(大)、create_time(小),若还有其他字段,则需要再次关联MAX的结果),影响字段越多,则关联的子查询越多,降低性能。
核心SQL如下:
SELECT
check.auth_user_id,
uo.id last_passed_order_id,
uo.create_time last_passed_order_create_time
FROM
user_order uo
INNER JOIN user_order_check check ON check.order_id = uo.id AND check.id = uo.sale_qc_check_id
/* 相同销售,按审核通过时间,取最近 */
INNER JOIN (
SELECT
auth_user_id,
MAX(check_time) max_time
FROM
user_order_check
WHERE
check_status = 200
AND auth_user_id IN (1,2,3)
GROUP BY
auth_user_id
) max_result_time ON max_result_time.auth_user_id = check.auth_user_id AND max_result_time.max_time = check.check_time
/* 相同销售,相同审核通过时间,取最近生成的订单(此类情况不易出现,如产品不考虑此类情况,可不关联该部分,有助于提高性能) */
INNER JOIN (
SELECT
auth_user_id,
MAX(order_id) max_order_id
FROM
user_order_check
WHERE
check_status = 200
AND auth_user_id IN (1,2,3)
GROUP BY
auth_user_id,
check_time
) max_result_order ON max_result_order.auth_user_id = check.auth_user_id AND max_result_order.max_order_id = check.order_id;
另:建议额外搭配合适的索引使用。