【问题标题】:insert select statement with changes to fields and logic thinking插入带有更改字段和逻辑思维的选择语句
【发布时间】:2013-04-10 19:37:05
【问题描述】:

我正在编写一些与创建经常性发票有关的 php 代码。我需要一些帮助来思考逻辑。我认为最终我会得到一种插入/选择语句。此处最终生成的 php 代码将在 nightly cron 中运行。

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

ID = 这是自动递增的主键,也恰好是发票编号。

recurring = 这是发票是一次性的还是经常性的。 O=一次,M=每月等

recurred = 这将在插入时设置为 N,这是我用来查看将在表中创建的下一张经常性发票是否应基于此发票的逻辑。当新的定期发票插入表中时,这将更改为 Y,因此 cron 作业不会再次对其进行处理。

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

所以这是我的逻辑。首先,我运行一个查询来查找所有不是 O 且 recurred = 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.) 如何创建插入选择语句来处理更改的变量和 2.) 如何处理如果发票是在一个月的 31 日创建并且下个月只有 30 的日期天(或 28 天)。

【问题讨论】:

    标签: php mysql date logic


    【解决方案1】:

    只取需要重新插入的行:

    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 vs boolean 是什么意思。你能详细说明一下吗?
    • Avetis,我将不得不计算每月(M)每季度(Q)每半年(S)每年(A)。自从您添加了 diff>= 30 后,您是否建议我为每种类型运行此查询?还是我应该运行一次并获取所有内容并使用 if 语句对其进行排序?
    • 关于枚举和布尔值,您使用字母 O、Y、N、M 作为“字符串”来标识事物,这对数据库不利,您应该根据自己的逻辑更改类型,所以如果您需要字段的是/否错字,它应该是布尔值(真/假)如果您有多个选项,例如每月/季度/每日,那么字段类型应该是枚举,您可以在其中获得确切的名称枚举(每天,每月.eg),这一切都会更有效地工作。
    • 关于不同类型的不同日期范围,你当然可以对每种类型进行多次查询,我假设不会太多。或者您可以做出更好的 WHERE 语句,例如 WHERE (recuring = 'M' AND diff >= 30) || (recuring = 'Y' AND diff >= 365) 例如并且在 PHP 代码中而不是 +1 个月使用 +1 年 +1 天,根据重复字段(通过使用 if's),所以在这种情况下,您将只选择一个查询,插入一个查询,然后进行一次 foreach 迭代PHP 中只有可更新的行。听起来不错?
    【解决方案2】:

    我做了一些类似的申请。就我而言,我有 2 张表:实际发票和经常性发票。循环表有一个名为 NextDate 的字段 - 应创建下一张发票的日期。一次发票直接添加到发票表中,否则 cron 作业会扫描循环表并检查 NextDate 值。如果是过去,则在发票表中生成新发票并更新 NextDate(通常按月递增)。

    在我的情况下,按月递增只会将月份值更改 1。例如在 MySQL 中

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

    【讨论】:

    • 我喜欢 nextdate 字段的想法,可以结合 Avetis 的建议使用。
    • 倒车时会发生什么?从 2013 年 1 月 31 日的发票开始。创建的下一张发票是 2-28-2013。下一个会是什么样子?会是 2013 年 3 月 31 日吗?
    • 我认为安全的赌注是使用原始日期 (1-31-2013) 并执行 INTERVAL 1、INTERVAL 2 等。
    • 原始日期=创建发票时输入的日期。 2 个月后,您再做 DATE_ADD('2008-01-31', INTERVAL 2 MONTHS)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多