Php 插入select语句,并更改字段和逻辑思维

Php 插入select语句,并更改字段和逻辑思维,php,mysql,date,logic,Php,Mysql,Date,Logic,我正在编写一些php代码,这些代码与创建定期发票有关。我需要一些帮助来思考逻辑。我想最终我会得到一种类型的Insert/Select语句。这里最终生成的php代码将在夜间cron中运行 首先,让我向您展示我的一些表项作为参考框架,并解释一下它们的作用。该表称为Invoice,还有其他与之相关的表,但我认为如果我现在能够确定这一表的逻辑,我可以将其应用于其他表 ID=这是自动递增的主键,同时也是发票号 重复=这是发票是一次性的还是重复的。O=一次,M=每月等 recurred=这将在插入时设置为N

我正在编写一些php代码,这些代码与创建定期发票有关。我需要一些帮助来思考逻辑。我想最终我会得到一种类型的Insert/Select语句。这里最终生成的php代码将在夜间cron中运行

首先,让我向您展示我的一些表项作为参考框架,并解释一下它们的作用。该表称为Invoice,还有其他与之相关的表,但我认为如果我现在能够确定这一表的逻辑,我可以将其应用于其他表

ID=这是自动递增的主键,同时也是发票号

重复=这是发票是一次性的还是重复的。O=一次,M=每月等

recurred=这将在插入时设置为N,这是我用来查看表中创建的下一个定期发票是否基于此发票的逻辑。将新的定期发票插入到表中时,该发票将更改为Y,以便cron作业不会再次处理该发票

日期=这是插入/创建发票的日期。例如,如果创建发票的日期是本月15日,则创建的下一张发票将是下月15日。本质上,M代表每月。然而,我还没有弄清楚如何处理创建日期31日,但下个月只有30天,可以在这里使用一些帮助

这就是我的逻辑。首先,我运行一个查询来查找所有不是O且递归=N的行

$result = mysql_query("SELECT * FROM invoice WHERE recurring != 'O' and recurred
='N')或死亡(mysql_error())

接下来,我研究了每种重复出现的每月M,每季度Q,等等

if recurring = M
 if todays date day = 'date' day
  copy line item into a new row with the following changes: new ID, todays date, and mark the recurred to N for the new insert (will mark the old one Y)
显然,这不是实际的代码,只是我在想的


因此,我的问题是1.)如何创建insert select语句来处理已更改的变量,2.)如何处理发票在一个月的31日创建,而下个月只有30天(或28天)的日期。

只取需要重新插入的行:

SELECT *, DATEDIFF(`date`, NOW()) as diff FROM invoice WHERE recuring != 'O' 
AND recured = 'N' AND diff >= 30;
迭代该列表,并通过以下公式计算每行的新日期:

$newDate = date("Y-m-d", strtotime($oldDate+" +1 month"));
这将解决您每月30日的问题

现在插入新创建的数据


另外,建议对重现字段使用enum,对重现字段使用boolean。

我做了一些类似的应用。在我的例子中,我有两个表:实际发票和重现发票。重现表有一个名为NextDate的字段,即创建下一张发票的日期。一次性发票直接添加到发票表中,其他ise cron作业扫描周期表并检查下一个日期值。如果该值为过去值,则会在发票表中生成新发票,并更新下一个日期(通常按月递增)

在我的例子中,按月递增只会将月份值更改1

DATE_ADD('2008-01-31', INTERVAL 1 MONTH)  --> 2008-02-29

谢谢,我会试一试。我不知道枚举和布尔值是什么意思。你能详细说明一下吗?阿维蒂斯,我将不得不对每月(M)季度(Q)半年(S)年度(a)进行计算。您是否建议我为每种类型运行此查询,因为您添加了diff>=30?还是应该运行一次,然后获取所有内容并使用if语句进行排序?关于枚举和布尔值,您使用字母O、Y、N、M作为“字符串”“要确定对数据库有害的内容,您应该根据您的逻辑更改类型,因此,如果您需要字段的“是/否”键入,则应为布尔值(真/假)。如果您有几个选项,如“每月/四分之一LU/每日”,则字段的类型应为enum,您可以在其中使用确切的名称enum(每日、每月,例如)。”对于不同类型的不同日期范围,您当然可以对每种类型进行多个查询,我假设没有太多。或者你可以制作一个更好的WHERE语句,比如WHERE(recuring='M'和diff>=30)| |(recuring='Y'和diff>=365),在PHP代码中,根据recuring字段(使用if's),使用+1年+1天,而不是+1个月,因此在这种情况下,你只需要选择一个查询,插入一个查询,以及在PHP中仅对可更新行的foreach迭代。听起来不错?我喜欢下一个日期字段的想法,可能会将其与Avetis的建议结合使用。当你反向操作时会发生什么?从日期为2013年1月31日的发票开始。下一张发票创建日期为2013年2月28日。下一个会是什么样子?会是2013年3月31日吗?我认为安全的方法是使用原始日期(2013年1月31日)并执行间隔1、间隔2等。原始日期=创建发票时输入的日期。2个月后,您需要添加日期(“2008-01-31”,间隔2个月)