【发布时间】:2017-05-30 18:56:56
【问题描述】:
我有一个名为subscriptions 的数据库表。表格中的每一行都有一个created_at 日期,从今天开始,每个月(之后)都必须为订阅开具发票。
因此,在 2017-05-29 上,所有具有 created_at 日 == '29' 的订阅都必须开具发票,无论月份或年份。于是我想到了这个:
SELECT * FROM subscriptions WHERE DAY(created_at) = DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))
但在这种情况下,当上个月有 30 天时,我会遇到麻烦,因为在 30 日,它返回 30,但在 31 日,它也返回 30。所以所有带有 created_at 天“30”的订阅都会开票两次。二月也会有问题。
另一个问题是反过来,如果 4 月没有第 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));
【问题讨论】:
-
如何:如果 LAST_DAY() = CURDATE() 目标所有日期的日期值 > 比今天的数字? ...我会看看我是否可以把它变成一个答案(除非有人打败我)。
-
@mickmackusa,我知道你要去哪里,但我还不知道如何完成它!
-
Strawberry 在该链接中有一个有效点。请通过编辑您的问题以包含一个小样本集来为良好的提问行为树立榜样。这将提高您的问题的教育质量。如果你这样做,我会支持你的问题。
标签: php mysql date sql-date-functions