【问题标题】:Fill MYSQL table with records based on date interval用基于日期间隔的记录填充 MYSQL 表
【发布时间】:2020-03-16 06:35:28
【问题描述】:

在 MYSQL v5 中,我想根据最新订单日期、订单之间的平均日期间隔(天)和平均订单价值创建每个客户 (CUSTID) 的线性预测,所有这些我已经按 CUSTID 查询过.

因此,我希望使用列 CUSTID、平均订单价值、该客户的最新订单日期和最大日期之间的每个日期的订单日期创建一条记录,比如说“2019-12-31”。

基于堆栈上有些类似的问题,我尝试了一个存储过程中的 while 循环(如下),但我很难获得任何有意义的输出,尽管我认为我离正确的道路不远。很感谢任何形式的帮助。

Input Data sample
+--------+------------+-------------+------------+
| CUSTID | LatestDate | AvgInterval | OrderValue |
+--------+------------+-------------+------------+
|   1001 | 01/11/2019 |          15 | 400.00     |
|   1002 | 17/10/2019 |           8 | 250.00     |
|   1003 | 04/11/2019 |           7 | 500.00     |
+--------+------------+-------------+------------+

Expected output table
+--------+------------+------------+
| CUSTID |    Date    | OrderValue |
+--------+------------+------------+
|   1001 | 16/11/2019 | 400.00     |
|   1001 | 01/12/2019 | 400.00     |
|   1001 | 16/12/2019 | 400.00     |
|   1001 | 31/12/2019 | 400.00     |
|   2002 | 29/10/2019 | 250.00     |
|   2002 | 10/11/2019 | 250.00     |
|   2002 | 22/11/2019 | 250.00     |
|   2002 | 04/12/2019 | 250.00     |
|   2002 | 16/12/2019 | 250.00     |
|   2002 | 28/12/2019 | 250.00     |
|   3003 | 13/11/2019 | 500.00     |
|   3003 | 22/11/2019 | 500.00     |
|   3003 | 01/12/2019 | 500.00     |
|   3003 | 10/12/2019 | 500.00     |
|   3003 | 19/12/2019 | 500.00     |
|   3003 | 28/12/2019 | 500.00     |
+--------+------------+------------+

The while loop I attempted to use for this:
while 
    (select max('Date') from OutputTable) <= '2019-12-31'
do
    insert into OutputTable
        (select 
            ip.CUSTID, 
            date_add(
                max(
                    ip.LatestDate, 
                    max(op.'Date')
                    ),
                interval ip.AvgInterval DAY    
                ) as 'Date',
            ip.OrderValue
        from
            InputTable ip,
            OutputTable ou
        )
end while

【问题讨论】:

  • 考虑处理应用代码中数据显示的问题

标签: mysql stored-procedures while-loop sql-insert


【解决方案1】:

在 MySQL 8.0 中,您可以使用递归查询:

with recursive cte as (
    select USTID, latestDate Date, AvgInterval, OrderValue from mytable 
    union all
    select USTID, Date + interval AvgInterval day, AvgInterval, OrderValue 
    from cte 
    where Date <=  '2019-12-31' - interval AvgInterval day
)
select USTID, Date, OrderValue from cte order by USTID, Date

Demo on DB Fiddle

USTID |日期 |订单价值 ----: | :--------- | ---------: 1001 | 2019-11-01 | 400.00 1001 | 2019-11-16 | 400.00 1001 | 2019-12-01 | 400.00 1001 | 2019-12-16 | 400.00 1001 | 2019-12-31 | 400.00 1002 | 2019-10-17 | 250.00 1002 | 2019-10-25 | 250.00 1002 | 2019-11-02 | 250.00 1002 | 2019-11-10 | 250.00 1002 | 2019-11-18 | 250.00 1002 | 2019-11-26 | 250.00 1002 | 2019-12-04 | 250.00 1002 | 2019-12-12 | 250.00 1002 | 2019-12-20 | 250.00 1002 | 2019-12-28 | 250.00 1003 | 2019-11-04 | 500.00 1003 | 2019-11-11 | 500.00 1003 | 2019-11-18 | 500.00 1003 | 2019-11-25 | 500.00 1003 | 2019-12-02 | 500.00 1003 | 2019-12-09 | 500.00 1003 | 2019-12-16 | 500.00 1003 | 2019-12-23 | 500.00 1003 | 2019-12-30 | 500.00

在早期版本中,典型的解决方案包括一个数字表。

select USTID, t.latestDate + interval d.n * t.AvgInterval day Date, OrderValue
from mytable t
inner join (
    select 0 n union all select 1 union all select 2 union all select 3 
    union all select 4 union all select 5 union all select 6 
    union all select 7 union all select 8 union all select 9
) d
    on t.latestDate + interval d.n * t.AvgInterval day <  '2019-12-31'

这将处理多达 10 个未来间隔。您可以使用更多 unions 扩展子查询以管理更多内容,或者更好的是您可以在查询中实现一个数字表和 join 它。

【讨论】:

  • 感谢 GMB,我将立即尝试您的建议。一项检查:我希望 d.latestDate 在您的示例中应该是 t.latestDate,对吗?
  • @ArjanPelle:是的,你是对的,我刚刚修正了那个错字。
  • 欢迎@ArjanPelle!
猜你喜欢
  • 1970-01-01
  • 2019-12-26
  • 2019-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-01
  • 2020-05-12
  • 1970-01-01
相关资源
最近更新 更多