【问题标题】:PHP and MySQL: Comparing month and day with dynamic yearPHP 和 MySQL:将月份和日期与动态年份进行比较
【发布时间】:2016-05-18 19:41:04
【问题描述】:

我正在处理的应用程序遇到了一些问题,我希望得到一些指导。

我有一个简单的预订系统:每件商品都有一个标准价格,但有些时期价格可能会发生变化。

例如:

  • 标准价格为100/天

  • 每年从Oct. 1stFeb. 1st,价格80/天

  • Jun. 1stAug. 31st每年的价格是120/天

  • [...] 最多 6 种不同的价格变化(季节)

因为这是每年一次,我只需要月份和日期,但我不知道如何将这些值存储在数据库中。我正在考虑有两个字段,一个代表月份,一个代表天,其中包含数值(01-12 代表月份,01-31 代表天)。这些值是由用户自己设置的,它们是相对于项目本身的,并不是每个人都固定的。

问题是当有人进行预订时,我需要检查是否需要更改价格,但我不明白如何构建查询来检查这一点。更糟糕的是,价格在预订期间可以有多个值。

按照上面的例子,如果我要从Sep. 1st (current year)Jul. 1st (next year) 预订商品,价格如下:

  • 100/天Sep. 1stSep. 30th

  • 80/天Oct. 1stFeb. 1st

  • 100/天来自Feb. 2ndto May 31st

  • 120/天Jun. 1stJul. 1st

有什么方法可以检查这些情况,而不必每天循环并检查数据库是否匹配?

谢谢

【问题讨论】:

    标签: php mysql date date-comparison


    【解决方案1】:

    查看日期时可以使用MySQLdate_format函数。

    例如:

    select date_format('2016-05-18', '%m%d');
    +-----------------------------------+
    | date_format('2016-05-18', '%m%d') |
    +-----------------------------------+
    | 0518                              |
    +-----------------------------------+
    1 row in set (0,01 sec)
    

    所以,你可以用简单的时间间隔检查:今天是0518,它在 2 月 2 日和 5 月 31 日之间:

    0202

    完整示例:

    desc mytable;
    +-----------+---------+------+-----+---------+-------+
    | Field     | Type    | Null | Key | Default | Extra |
    +-----------+---------+------+-----+---------+-------+
    | date_from | char(4) | YES  |     | NULL    |       |
    | date_to   | char(4) | YES  |     | NULL    |       |
    | price     | int(11) | YES  |     | NULL    |       |
    +-----------+---------+------+-----+---------+-------+
    3 rows in set (0,00 sec)
    
    select * from mytable;
    +-----------+---------+-------+
    | date_from | date_to | price |
    +-----------+---------+-------+
    | 0901      | 0930    |   100 |
    | 1001      | 0201    |    80 |
    | 0202      | 0531    |   100 |
    | 0601      | 0701    |   120 |
    +-----------+---------+-------+
    4 rows in set (0,00 sec)
    

    示例查询:

    select price, date_from, date_to from mytable where date_format(now(), '%m%d') between date_from and date_to;
    +-------+-----------+---------+
    | price | date_from | date_to |
    +-------+-----------+---------+
    |   100 | 0202      | 0531    |
    +-------+-----------+---------+
    1 row in set (0,01 sec)
    

    编辑

    阅读您对@FelipeDuarte 回答的评论...从 10/01(10 月 1 日)到 02/01(2 月 1 日)期间,我们需要考虑新的一年...

    您可以通过将时段分成两个时段来作弊:10/01 到 12/31 和 01/01 到 02/01

    【讨论】:

    • 非常感谢您的帮助。所以现在我可以找到某个日期的价格。但我的问题是我找不到日期范围的价格。你是在建议我每天查询吗?因此,如果我预订 10 天,从 9 月 1 日到 9 月 11 日,我必须循环 10 次才能找到合适的价格。这是正确的吗 ?我知道性能会有点差,但我最多可以预订 30 天。再次感谢您
    • 希望这个answer 可能有用。
    • 但我理解您的问题略有不同:如果给定的时间段与两个时间段重叠,则会有 2 个不同的价格...
    • 是的,给定用户想要预订商品的范围,价格可能每天都不同(最坏的情况)。也许两天是 100,另外两天是 80,三天是 150,依此类推,具体取决于表中的总周期。最后我想我可能只是每天查询并添加价格:正如我所说,最多可能会有 30/40 天
    • 或者你可以用不同的方式来做。查询所有时段(及其每日价格)并根据预订时段检查适当的时段。在 PHP 中操作应该更快更容易。
    【解决方案2】:

    我不知道你的数据库表,但我认为你可以这样做:

    1. 获取您的经期、iniDay、iniMonth、endDay、endMonth
    2. 您的表需要有这些字段:ini_day、ini_month、ini_daymonth、end_day、end_month、end_daymonth、price_day
    3. SELECT * from table WHERE iniDay >= booking_ini_day AND iniMonth >= booking_ini_month -- get initial period AND iniDay <= booking_end_day AND iniMonth <= booking_end_month UNION ALL SELECT * from table WHERE iniDay <= booking_ini_day AND iniMonth <= booking_ini_month -- get middle periods AND endDay >= booking_end_day AND endMonth >= booking_end_month UNION ALL SELECT * from table WHERE endDay >= booking_ini_day AND endMonth >= booking_ini_month AND endDay <= booking_end_day AND endMonth <= booking_end_month -- get end period
    4. 计算结果查询中每个周期/行的天数并显示给您的用户。

    您将“复制”数据库信息,例如日、月和日月,但这是为了获得更好的性能。

    【讨论】:

    • 目前我的表格的结构与您描述的一样,只是我没有组合月份和日期的字段。我会立即进行一些测试并回复您。谢谢
    • 不幸的是它不起作用。用户预订的日期不一定在某个范围内,但只有某些天可能,因此 where 子句不正确。
    • 谢谢,我试试。但是看到你的查询,如果所有的比较都是用单日和单月进行的,那么此时 daymonth 字段的目的是什么?
    • 如果您需要进行另一次比较、查询、排序、分组、添加年份或仅显示该信息,它已经在您手中。无需转换或连接数据。
    猜你喜欢
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-22
    • 2020-12-03
    相关资源
    最近更新 更多