0

这是表的基本设置(仅存在相关列的 DDL)。MySQL 版本 8.0.15

目的是显示订单之间的平均日期差异间隔。

    CREATE TABLE final (
    prim_id INT(11) NOT NULL AUTO_INCREMENT,
    order_ID INT(11) NOT NULL,
    cust_ID VARCHAR(45) NOT NULL,
    created_at DATETIME NOT NULL,
    item_name VARCHAR(255) NOT NULL,
    cust_name VARCHAR(255) NOT NULL,
    PRIMARY KEY (prim_id),
    COLLATE='latin1_swedish_ci'
    ENGINE=InnoDB
    AUTO_INCREMENT=145699

附加信息:

cust ID -> cust_name (one-to-many)
cust_ID -> order_ID (one-to-many)
order ID -> item_name (one-to-many)
order ID -> created_at (one-to-one)
prim_id -> *everything* (one-to-many)

我曾想过使用 min(created_at) 和 max(created_at) 但这将排除最旧和最新之间的所有订单。我需要一个更精致的解决方案。

最终结果应该是这样的:

有关所有订单之间的平均时间间隔的信息(不仅仅是最小和最大,因为经常有两次以上的时间),以天为单位,在显示客户名称 (cust_name) 的列旁边。

4

1 回答 1

1

如果我做对了,您可能会使用子查询来获取上一个订单的日期。用于datediff()获取日期之间的差异并获取该差异avg()的平均值。

SELECT f1.cust_id,
       avg(datediff(f1.created_at,
                    (SELECT f2.created_at
                            FROM final f2
                            WHERE f2.cust_id = f1.cust_id
                                  AND (f2.created_at < f1.created_at
                                        OR f2.created_at = f1.created_at
                                           AND f2.order_id < f1.order_id)
                            ORDER BY f2.created_at DESC,
                                     f2.order_id DESC
                            LIMIT 1)))
       FROM final f1
       GROUP BY f1.cust_id;

编辑:

如果一个订单 ID 可以有更多行,正如 KIKO Software 提到的,我们需要SELECT从不同的订单集中执行,例如:

SELECT f1.cust_id,
       avg(datediff(f1.created_at,
                    (SELECT f2.created_at
                            FROM (SELECT DISTINCT f3.cust_id,
                                                  f3.created_at,
                                                  f3.order_id
                                         FROM final f3) f2
                            WHERE f2.cust_id = f1.cust_id
                                  AND (f2.created_at < f1.created_at
                                        OR f2.created_at = f1.created_at
                                           AND f2.order_id < f1.order_id)
                            ORDER BY f2.created_at DESC,
                                     f2.order_id DESC
                            LIMIT 1)))
       FROM (SELECT DISTINCT f3.cust_id,
                             f3.created_at,
                             f3.order_id
                    FROM final f3) f1
       GROUP BY f1.cust_id;

如果订单可能有两行具有不同的客户 ID 或不同的创建时间戳,这可能会失败。但在这种情况下,数据完全是垃圾,需要先纠正。


第二次编辑:

或者,如果这些可能不同,则获取每个订单的最大创建时间戳:

SELECT f1.cust_id,
       avg(datediff(f1.created_at,
                    (SELECT f2.created_at
                            FROM (SELECT max(f3.cust_id) cust_id,
                                         max(f3.created_at) created_at,
                                         f3.order_id
                                         FROM final f3
                                         GROUP BY f3.order_id) f2
                            WHERE f2.cust_id = f1.cust_id
                                  AND (f2.created_at < f1.created_at
                                        OR f2.created_at = f1.created_at
                                           AND f2.order_id < f1.order_id)
                            ORDER BY f2.created_at DESC,
                                     f2.order_id DESC
                            LIMIT 1)))
       FROM (SELECT max(f3.cust_id) cust_id,
                    max(f3.created_at) created_at,
                    f3.order_id
                    FROM final f3
                    GROUP BY f3.order_id) f1
       GROUP BY f1.cust_id;
于 2019-03-29T11:36:28.273 回答