MySQL 查詢結果倒敘後分組(先order by,再按order by的結果group by)

業務前提:用戶下單,訂單歸屬於指定銷售,審覈通過的訂單可以參與計算業績。
需求描述:統計向,統計銷售成單情況,要求顯示指定銷售人員最近審覈通過的訂單。

解決方案:暫列舉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;

另:建議額外搭配合適的索引使用。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章