【问题标题】:Show next date based on criteria根据条件显示下一个日期
【发布时间】:2023-03-18 16:51:01
【问题描述】:

在 perl 中,我有以下数据库查询:

   my $list = $db->SelectARef("SELECT p.*, u.usr_login, u.usr_money, u.usr_email, u.usr_pay_email, u.usr_pay_type
                           FROM Payments p, Users u
                           WHERE status='PENDING'
                           AND p.usr_id=u.usr_id
                           ORDER BY u.usr_pay_type");

在数组结果中有一个名为“created”的字段。

我想要做的是在数组中为每一行添加另一个元素作为“下一次付款”。

付款会在从日期时间值算起的 30 天后处理,但仅在每个月的第 6 天处理。基本上,我希望每个结果都有一个“下一次付款”元素,说明他们应该在哪一天和哪一个月获得付款。

例如创建 = 2013-07-29 18:55:37 30 天后是 2013 年 8 月 28 日 因此,下一个付款日期将是 9 月 6 日

我不知道从哪里开始,任何人都可以提供任何帮助将不胜感激!

谢谢

【问题讨论】:

    标签: mysql perl datetime


    【解决方案1】:

    逻辑如下:

    select (date(t) - interval (day(t) - 1) day) + interval 1 month + interval 5 day
    from (select cast(now() as datetime) as t) t;
    

    您可以将其放入查询中:

    SELECT p.*, u.usr_login, u.usr_money, u.usr_email, u.usr_pay_email, u.usr_pay_typel,
           created - interval (day(created) - 1) day) + interval 1 month + interval 5 day as nextpay
    FROM Payments p join
         Users u
         on p.usr_id=u.usr_id
    WHERE status='PENDING' 
    ORDER BY u.usr_pay_type;
    

    表达式可以简化为:

           created - interval (day(created) + 4) day) + interval 1 month as nextpay
    

    【讨论】:

    • 我看不出这将如何给出下一个付款日期或者我错过了什么?看起来我只有一个月的时间?
    • @papa_face 。 . .您是否运行了第一个查询?它返回下个月的第 6 天。
    • my $list = $db->SelectARef("SELECT p.*, u.usr_login, u.usr_money, u.usr_email, u.usr_pay_email, u.usr_pay_type, p.created - 间隔 ( day(p.created) + 4) day) + 间隔 1 个月作为 nextpay FROM Payments p,用户 u WHERE status='PENDING' AND p.usr_id=u.usr_id ORDER BY u.usr_pay_type");我收到此错误:在第 1 行使用 ') + 间隔 1 个月作为 nextpay FROM Payments p, ' 附近的语法
    【解决方案2】:

    如果我理解正确,您想计算一个 next_payment 日期,它是一个月中最近的第 6 天,距离 created 日期至少 30 天。另一种说法是,您的截止日期始终是每月的 6 日,并且从截止日期算起至少有 30 天的宽限期。

    很遗憾,我们不能在这里进行简单的舍入或步进,因为公历并不是一个规则的系列。 (这完全不是一个常规系列?)所以,我们将条件逻辑放入查询中。由于这看起来很糟糕,我们将其隐藏在一个函数中:

    DELIMITER //
    CREATE FUNCTION next_payment(close_date DATE)
    RETURNS DATE
      DETERMINISTIC
      READS SQL DATA
      LANGUAGE SQL
    BEGIN
      DECLARE min_grace INT  DEFAULT 30; -- minimum grace period of 30 days
      DECLARE bill_dom  INT  DEFAULT  6; -- billing day of month is the 6th
      DECLARE d         DATE;
    
      SET d = close_date + INTERVAL min_grace DAY;
    
      IF DAY(d) > bill_dom THEN                    -- Did 30 days\' grace put us beyond the 6th?
        SET d = d + INTERVAL 1 MONTH;              -- If so, advance to next month.
      END IF;
    
      RETURN d + INTERVAL(bill_dom - DAY(d)) DAY;  -- Now "round" to the 6th of the month
    END
    //
    DELIMITER ;
    

    如何使用逻辑取决于您。添加SELECT next_payment(p.created) AS "next_payment", ... 将为您提供所需的附加列。您可以参数化上述内容(例如,CREATE FUNCTION next_payment(close_date DATE, min_grace INT, bill_dom INT))以获得更大的灵活性。您可能会将 SET/IF 逻辑从函数中剥离出来,并将其塞进 SELECT 中一个笨拙的 CASE/END 语句中。您可以创建一个 VIEW 自动将 next_payment 列“附加”到表中,或者创建一个 ALTER TABLE 并填充一个新列,等等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-06
      • 1970-01-01
      • 1970-01-01
      • 2012-07-14
      • 1970-01-01
      • 2022-01-03
      • 2013-03-18
      • 1970-01-01
      相关资源
      最近更新 更多