Mysql 根据条件显示下一个日期

Mysql 根据条件显示下一个日期,mysql,perl,datetime,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'

在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”的字段

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

自datetime值起满30天后才处理付款,但仅在每月的第6天处理。基本上,我希望每个结果都有一个“下次付款”元素,说明他们应该在哪一天和哪一个月付款

e、 g=2013-07-2918:55:37 30天后,即2013年8月28日 因此,下一个付款日期是9月6日

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


谢谢

下面显示了逻辑:

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

如果我理解正确,您需要计算一个
下一次付款
日期,该日期是一个月中最接近的第6天,距离
创建日期至少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 ;

如何使用逻辑取决于你自己。添加
选择next\u payment(p.created)作为“next\u payment”…
将为您提供所需的附加列。您可以将上述参数化(例如,
CREATE FUNCTION next\u payment(close\u date date,min\u grace INT,bill\u dom INT)
)以获得更大的灵活性。您可能会将SET/IF逻辑从函数中剥离出来,并将其塞进SELECT中一个笨拙的CASE/END语句中。您可以创建一个视图,自动在表中“附加”一个
next\u payment
列,或者更改表并填充一个新列,等等。

我看不出这将如何给出下一个付款日期,或者我是否错过了什么?看起来好像我刚过了一个月?@papa_face。您是否运行了第一个查询?它返回下个月的第6天。my$list=$db->SelectARef(“选择p.*,u.usr\u登录,u.usr\u金钱,u.usr\u电子邮件,u.usr\u支付电子邮件,u.usr\u支付类型,p.created-间隔(p.created)+4天)+从付款p开始的下一个月间隔1个月,用户u的状态为“待定”且p.usr_id=u.usr_id按u.usr_支付类型订购”);我得到了这个错误:语法使用near')+interval 1 month作为第1行付款p'的下一个付款