根据标准显示下一个日期

时间:2013-08-25 17:25:26

标签: mysql perl datetime

在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天处理。基本上我希望每个结果都有一个“下一个付款”元素,说明他们应该支付哪个日期和月份。

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

我不知道从哪里开始,任何人都可以提供的帮助将非常感谢!

由于

2 个答案:

答案 0 :(得分:0)

以下显示逻辑:

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

答案 1 :(得分:0)

如果我理解正确,您希望计算next_payment日期,该日期是距离created日期至少30天的最近的第6天。另一种说法是,您的截止日期始终是该月的第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并填充新列等。