PHP中的递归逻辑&x2B;MySQL

PHP中的递归逻辑&x2B;MySQL,php,mysql,Php,Mysql,我正在尝试应用递归逻辑 我在tbl_约会表中有以下数据(recurr_type:1=每周,2=每月,0=非递归): 我有以下获取数据的标准:如果我获取2014年7月(第7个月)的数据,那么 获取约会id(21)(1行)并 appointment\u id(18)是每周递归的,取7月份的重复次数(4行): 注意:日期更改是因为约会是每周循环的,这意味着我在每个日期上加了7天。2014-06-02+7天=2014-06-09,依此类推。因此,7月份的日期为2014-07-07 appointment

我正在尝试应用递归逻辑

我在
tbl_约会
表中有以下数据(
recurr_type
:1=每周,2=每月,0=非递归):

我有以下获取数据的标准:如果我获取2014年7月(第7个月)的数据,那么

  • 获取约会id(21)(1行)并
  • appointment\u id(18)
    是每周递归的,取7月份的重复次数(4行):

    注意:日期更改是因为约会是每周循环的,这意味着我在每个日期上加了7天。2014-06-02+7天=2014-06-09,依此类推。因此,7月份的日期为2014-07-07

  • appointment\u id(19)
    是每月递归的,取7月份的重复次数(1行):

    注意:日期更改是因为每个月的约会都是递归的,这意味着我在日期上加了一个月

  • 最终输出为(共6行):

    我尝试了以下代码:

    SELECT
        tu.email,
        ta.appointment_id,
        ta.user_id,
        ta.date,
        ta.time,
        ta.recur_type,
        0 recursive
    FROM
        tbl_appointment ta
            LEFT JOIN
        tbl_user tu ON ta.user_id = tu.user_id
    WHERE
        1 AND YEAR(ta.date) = '2014'
          AND MONTH(ta.date) = '06'
          AND ta.user_id = 56
    UNION ALL SELECT
        tu.email,
        ta.appointment_id,
        ta.user_id,
        ta.date,
        ta.time,
        ta.recur_type,
        1 recursive
    FROM
        tbl_appointment ta
            LEFT JOIN
        tbl_user tu ON ta.user_id = tu.user_id
    WHERE
        1 AND recur_type = '2'
          AND ta.user_id = 56
    UNION ALL SELECT
        tu.email,
        ta.appointment_id,
        ta.user_id,
        ta.date,
        ta.time,
        ta.recur_type,
        2 recursive
    FROM
        tbl_appointment ta
            LEFT JOIN
        tbl_user tu ON ta.user_id = tu.user_id
    WHERE
        1 AND recur_type = '1'
          AND ta.user_id = 56
    ORDER BY date DESC, time
    

    如何满足上述要求?

    对每个递归类型使用联合查询

    每周和每月递归使用两个交叉连接的查询来生成一系列要添加到日期的数字。这可以处理多达1000次的重复预约,但很容易扩展到更多(如果预约要重复20年以上)

    SQL fiddle用于此:-


    谢谢你的回答。你能解释一下,10周和10个月是怎么做的吗?为什么要重复
    选择0 i UNION
    10次?抱歉,我无法理解。两个交叉连接的子查询分别生成从0到9的数字范围。当它们交叉连接在一起时,它们给出每一个数字组合(即,100个组合)。因此,使用
    units.i+tens.i*10
    它可以生成从0到100的数字(它可以很容易地扩展到交叉连接到1000,以此类推)。然后将其添加为开始日期的周数或月数(取决于查询),从而放弃100个重复约会日期(因为第一个数字为0,包括第一次约会)。您想使用“重复”这个词吗?“递归”在这种情况下听起来不太合适,但我不是以英语为母语的人。是的,它应该是递归的。
    appointment_id    user_id    date        recur_type    .....
    18                56         2014-07-07  1
    18                56         2014-07-14  1
    18                56         2014-07-21  1
    18                56         2014-07-28  1
    
    appointment_id    user_id    date        recur_type    .....
    19                56         2014-07-15  2
    
    appointment_id    user_id    date        recur_type    .....
    21                56         2014-07-20  2
    18                56         2014-07-04  1
    18                56         2014-07-11  1
    18                56         2014-07-18  1
    18                56         2014-07-15  1
    19                56         2014-07-15  2
    
    SELECT
        tu.email,
        ta.appointment_id,
        ta.user_id,
        ta.date,
        ta.time,
        ta.recur_type,
        0 recursive
    FROM
        tbl_appointment ta
            LEFT JOIN
        tbl_user tu ON ta.user_id = tu.user_id
    WHERE
        1 AND YEAR(ta.date) = '2014'
          AND MONTH(ta.date) = '06'
          AND ta.user_id = 56
    UNION ALL SELECT
        tu.email,
        ta.appointment_id,
        ta.user_id,
        ta.date,
        ta.time,
        ta.recur_type,
        1 recursive
    FROM
        tbl_appointment ta
            LEFT JOIN
        tbl_user tu ON ta.user_id = tu.user_id
    WHERE
        1 AND recur_type = '2'
          AND ta.user_id = 56
    UNION ALL SELECT
        tu.email,
        ta.appointment_id,
        ta.user_id,
        ta.date,
        ta.time,
        ta.recur_type,
        2 recursive
    FROM
        tbl_appointment ta
            LEFT JOIN
        tbl_user tu ON ta.user_id = tu.user_id
    WHERE
        1 AND recur_type = '1'
          AND ta.user_id = 56
    ORDER BY date DESC, time
    
    SELECT a.appoinemnt_id, a.user_id, a.recur_type, a.date AS appoint_date
    FROM tbl_appointment a
    WHERE a.recur_type = 0
    HAVING appoint_date BETWEEN '2014-07-01' AND '2014-07-31'
    UNION
    SELECT a.appoinemnt_id, a.user_id, a.recur_type, DATE_ADD(a.date, INTERVAL units.i + tens.i * 10 WEEK) AS appoint_date
    FROM tbl_appointment a
    CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)units
    CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)tens
    WHERE a.recur_type = 1
    HAVING appoint_date BETWEEN '2014-07-01' AND '2014-07-31'
    UNION
    SELECT a.appoinemnt_id, a.user_id, a.recur_type, DATE_ADD(a.date, INTERVAL units.i + tens.i * 10 MONTH) AS appoint_date
    FROM tbl_appointment a
    CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)units
    CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)tens
    WHERE a.recur_type = 2
    HAVING appoint_date BETWEEN '2014-07-01' AND '2014-07-31'