简体   繁体   English

计算平均日期差

[英]Calculate the average date difference

This is the essential setup of the table (only the DDL for relevant columns is present). 这是表的基本设置(仅存在相关列的DDL)。 MySQL version 8.0.15 MySQL版本8.0.15

The intent is to show an average of date difference interval between orders. 目的是显示订单之间日期差异间隔的平均值。

    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

Additional information: 附加信息:

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)

I've thought of using min(created_at) and max(created_at) but that will exclude all the orders between oldest and newest. 我已经考虑过使用min(created_at)和max(created_at),但是这将排除最旧和最新之间的所有顺序。 I need a more refined solution. 我需要一个更完善的解决方案。

The end result should be like this: 最终结果应如下所示:

Information about average time intervals between all orders, (not just min and max because there are quite often times, more than two) measured in days, next to a column showing the client's name (cust_name). 在显示客户名称(cust_name)的列旁边,以天为单位,以天为单位,显示所有订单之间的平均时间间隔的信息(不只是最小和最大,因为经常会有两个以上的时间)。

If I get this right you might use a subquery getting the date of the previous order. 如果我理解正确,则可以使用子查询获取上一个订单的日期。 Use datediff() to get the difference between the dates and avg() to get the average of that differences. 使用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;

Edit: 编辑:

If there can be more rows for one order ID, as KIKO Software mentioned we need to do the SELECT from the distinct set of orders like: 如果一个订单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;

This may fail if there can be two rows for an order with different customer IDs or different creation time stamps. 如果对于具有不同客户ID或不同创建时间戳的订单,可以有两行,则可能会失败。 But in that case the data is just complete garbage and needs to be corrected before anything else. 但是在那种情况下,数据只是完全的垃圾,需要先进行纠正。


2nd Edit: 第二次编辑:

Or alternatively getting the maximum creation timestamp per order if these can differ: 或者,如果不同,则获得每个订单的最大创建时间戳记:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM