1

在 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 日

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

谢谢

4

2 回答 2

0

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

于 2013-08-27T04:07:50.187 回答
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
于 2013-08-25T17:43:28.963 回答