【问题标题】:How do I find the 2nd most recent order of a customer如何找到客户的第二个最新订单
【发布时间】:2020-01-19 19:45:23
【问题描述】:

我通过在 created_at 字段(按电子邮件分组)上执行 MIN 和 MAX 来获得客户的第一个订单日期和最后一个订单日期,但我还需要获得客户的第二个最近订单日期(订单日期正好在最后一个订单日期之前)订购日期)

SELECT 
    customer_email, 
    COUNT(entity_id) AS NumberOfOrders, 
    MIN(CONVERT_TZ(created_at,'UTC','US/Mountain')) AS 'FirstOrder', 
    MAX(CONVERT_TZ(created_at,'UTC','US/Mountain')) AS 'MostRecentOrder',
    SUM(grand_total) AS TotalRevenue, 
    SUM(discount_amount) AS TotalDiscount
FROM sales_flat_order 
WHERE 
    customer_email IS NOT NULL
    AND store_id = 1
GROUP BY customer_email
LIMIT 500000

【问题讨论】:

    标签: mysql sql max


    【解决方案1】:

    使用窗口函数ROW_NUMBER()(MySQL 8.0可用):

    SELECT *
    FROM (
        SELECT 
            t.*, 
            ROW_NUMBER() OVER(PARTITION BY customer_email ORDER BY created_at) rn_asc,
            ROW_NUMBER() OVER(PARTITION BY customer_email ORDER BY created_at DESC) rn_desc
        FROM sales_flat_order
        WHERE customer_email IS NOT NULL AND store_id = 1
    ) x
    WHERE rn_asc = 1 OR rn_desc <= 2
    

    这将为您提供每位客户下的最早和两个最新订单。

    注意:时区转换的目的尚不清楚。我把它们分开了,因为它们显然不会影响排序顺序;随意根据您的用例添加它们。


    如果您希望每个客户有一条记录,以及其订单总数,以及他的第一个、最后一个和最后一个订单的日期,那么您可以在外部查询中聚合:

    SELECT 
        customer_email,
        NumberOfOrders,
        MAX(CASE WHEN rn_asc = 1 THEN created_at END) FirstOrder,
        MAX(CASE WHEN rn_desc = 1 THEN created_at END) MostRecentOrder,
        MAX(CASE WHEN rn_desc = 2 THEN created_at END) MostRecentButOneOrder,
        TotalRevenue,
        TotalDiscount
    FROM (
        SELECT 
            customer_email,
            created_at,
            COUNT(*) OVER(PARTITION BY customer_email) NumberOfOrders,
            SUM(grand_total) OVER(PARTITION BY customer_email) TotalRevenue, 
            SUM(discount_amount) OVER(PARTITION BY customer_email) TotalDiscount,
            ROW_NUMBER() OVER(PARTITION BY customer_email ORDER BY created_at) rn_asc,
            ROW_NUMBER() OVER(PARTITION BY customer_email ORDER BY created_at DESC) rn_desc
        FROM sales_flat_order
        WHERE customer_email IS NOT NULL AND store_id = 1
    ) x
    GROUP BY customer_email
    

    【讨论】:

    • 非常感谢您的快速回复!太棒了。我仍在深入研究并试图弄清楚!我不知道 ROW_NUMBER 和 PARTITION BY,所以我非常感谢你,我会继续阅读和研究。对于内部查询,我收到一个错误,我现在正在尝试找出错误代码:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 4 行的 '(PARTITION BY customer_email) NumberOfOrders, SUM(grand_total) OVER(PAR' 附近使用正确的语法
    • @ChristopherV:您使用的是哪个版本的 MySQL?您可以运行SELECT @@vrsion 找出答案。
    • 5.6.33-0ubuntu0.14.04.1-log --- 啊悲伤的一天,适用于 8.0 - 嗯
    • @ChristopherV:不幸的是,在 MySQL 8.0 中添加了窗口函数(例如 ROW_NUMBER()),如我的回答中所示。你可以考虑升级你的数据库吗? 5.6 是旧版本。
    • 是的 - 我一定会这样做。但是知道在 5.6 上获得第二个最新订单的任何解决方法吗?
    猜你喜欢
    • 2021-04-09
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 2015-04-29
    • 1970-01-01
    • 2020-02-20
    相关资源
    最近更新 更多