php - MySQL 获取考虑不同月份长度的月度发票记录

标签 php mysql date sql-date-functions

我有一个名为 subscriptions 的数据库表。表格中的每一行都有一个 created_at 日期,从这一天开始,每个月(之后)都必须为订阅开具发票。

因此在 2017-05-29,所有 created_at day == '29' 的订阅都必须开具发票,无论是月份还是年份。所以我想到了这个:

SELECT * FROM subscriptions WHERE DAY(created_at) = DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))

但在那种情况下,如果上个月有 30 天,我就会遇到麻烦,因为在 30 日,它返回 30,但在 31 日,它也返回 30。所以所有具有 created_at 的订阅“30”日将开具两次发票。 2 月也会出问题。

另一个问题反过来,如果四月没有第31天,我将如何开发票2017-03-31。

我可以在 PHP 中进行多次检查并检查当月是否已经开具发票等。但我想知道我是否可以使用 MySQL 解决这个问题。

我创建了一个 sqlfiddle例如,基于上面的查询,有些日期会失败。

# Create subscription table
CREATE TABLE `subscription` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `company` varchar(100) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# Fill subscription table
INSERT INTO `subscription` (`id`, `company`, `created_at`)
VALUES
    (1, 'Acme', '2017-04-15 09:56:00'),
    (2, 'Equmbo', '2017-02-28 10:00:00'),
    (3, 'Megajo', '2017-03-31 08:10:34'),
    (4, 'Astrotude', '2017-04-30 08:10:49');

# This is my base query for monthly invoice
SELECT * FROM subscription WHERE DAY(created_at) = DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH));

# On 28th March, also fine
SELECT * FROM subscription WHERE DAY(created_at) = DAY(DATE_SUB('2017-03-28', INTERVAL 1 MONTH));

# But on 29th March, Equmbo is invoice again
SELECT * FROM subscription WHERE DAY(created_at) = DAY(DATE_SUB('2017-03-29', INTERVAL 1 MONTH));

# On 30st April, Astrotude AND Megajo must be invoiced. Only Astrotude returns.
SELECT * FROM subscription WHERE DAY(created_at) = DAY(DATE_SUB('2017-04-30', INTERVAL 1 MONTH));

最佳答案

WHERE
    /* don't invoice new subs from this month */
    LAST_DAY(created_at)<LAST_DAY(CURDATE())
    AND
    (
    /* exactly match sub's day value with today's day value */
    DAY(created_at)=DAY(CURDATE())
    OR
    /* on last day of month, match sub's day if greater than today's day */
    (CURDATE()=LAST_DAY(CURDATE()) AND DAY(created_at)>DAY(CURDATE()))   
    )

CURDATE()LAST_DAY()返回完整的日期字符串 (yyyy-mm-dd)。

DAY()返回一个整数(d 或 dd)。

关于php - MySQL 获取考虑不同月份长度的月度发票记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44250165/

相关文章:

php - 预期的 URL 重定向 + 登录后的默认重定向?

php 数组 foreach 循环

php - 在输入字段中创建一个跨度,例如 Facebook 消息

php - 仅当 "rare"列值= 1时如何导出mysql数据

mysql - 连接三个不同的mysql查询表

Java 日期月差

php运行一次并在mysql数据库中插入两次

mysql - 如何使用原始 SQL 确定 MySQL 中的 csv 格式字段中是否包含特定值?

java - 在 joda time 中创建自定义日历

C++ Store Date 对象中的日期是多少天前