-2

我有一个最新的 mysql 数据库安装,我需要一个函数来计算上个月第 n 天到今天之间的销售额。该函数每天将被调用多次,因为我正在寻找自上个月第 n 天以来的累计销售额超过阈值的点。

背景是我正在开发一个订阅网站。客户将在一年中的特定日期注册并全年进行购买。我希望能够计算本月至今的销售额。

如果客户在当月的第 n 天注册,那么我需要计算前 n 天到今天之间的销售额。

如果客户在 28 日注册,而今天是 30 日,那么您会认为只有 2 天的销售,但如果今天是 3 月 30 日,那么已经是 30 天了。在另一个例子中:如果客户在 10 月 31 日注册,这将如何处理 2 月 28 日或 4 月 30 日?

我查看了诸如 timestampdiff() 之类的函数,但无法找到实用的解决方案。我的意思是一个可以完成工作并且可以有效地完成任务而不会花费太多CPU周期的人。

感谢期待

4

3 回答 3

0

您可能正在寻找类似的东西:

DATE_ADD(
    LAST_DAY(DATE_SUB(CURDATE(), interval 2 MONTH)), 
    INTERVAL 15 DAY
)

给定天数N,它返回N上个月的第 th 天。

到今天为止,当给定 15 天时,这将产生'2018-12-15'(上个月的第 15 天,例如 2018 年 12 月 15 日)。

如果要确保返回的日期永远不会超过上个月的最后一天(例如:当前月份是三月和N = 31),您可以使用:

LEAST(
   DATE_ADD(
       LAST_DAY(DATE_SUB(CURDATE(), interval 2 MONTH)), 
       INTERVAL 15 DAY),
   LAST_DAY(DATE_SUB('CURDATE(), interval 1 MONTH))
)

通常,这:

SELECT LEAST(
   DATE_ADD(
       LAST_DAY(DATE_SUB('2018-03-28', interval 2 MONTH)), 
       INTERVAL 31 DAY),
   LAST_DAY(DATE_SUB('2018-03-28', interval 1 MONTH))
)

收益率:-('2018-02-28'二月的最后一天)。

于 2019-01-06T14:11:37.520 回答
0

我可以推荐 TIMESTAMP 和 INTERVAL。它简单高效,无需尝试做一些足够琐碎的事情

所以考虑以下模式和查询

DROP TABLE IF EXISTS `example_sales`;
CREATE TABLE `example_sales`(
  `id` INT(11) UNSIGNED AUTO_INCREMENT,
  `id_customer` MEDIUMINT(8) UNSIGNED NOT NULL,
  `profits` DECIMAL(16,2) NOT NULL DEFAULT 0,
  `ts` TIMESTAMP NOT NULL,
  PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;

-- add some values, it doesn't matter the order in the example
INSERT INTO `example_sales`( `id_customer`, `profits`, `ts` ) VALUES
  ( 1, 10.00, NOW( ) - INTERVAL 12 DAY ),
  ( 1, 14.00, NOW( ) - INTERVAL 1 WEEK ),
  ( 1, 110.00, NOW( ) - INTERVAL 30 DAY ),
  ( 1, 153.00, NOW( ) - INTERVAL 8 DAY ),
  ( 1, 5.00, NOW( ) - INTERVAL 2 DAY ),
  ( 1, 97.00, NOW( ) - INTERVAL 13 DAY ),
  ( 1, 1.00, '2018-02-28 13:00:00' ),
  ( 1, 2.00, '2018-03-28 13:00:00' ),
  ( 1, 3.00, '2018-01-30 13:00:00' ),
  ( 1, 4.00, '2018-03-30 13:00:00' ),
  ( 1, 42.00, NOW( ) - INTERVAL 42 DAY );

更新了,因为我最初并没有完全理解这个问题。我保留了时间戳,并做了一些我之前没有注意到的更正。

-- '2018-03-28' or '2018-03-29' instead of NOW( ) or anything you like
SET @last  := DATE( NOW( ) ); 
SET @first := LEAST( DATE_SUB( @last, INTERVAL 1 MONTH ), LAST_DAY( DATE_SUB( @last, INTERVAL 1 MONTH ) ) );

-- change last and first test different sets
SELECT `profits`, DATE( `ts` ) AS `date`
  FROM `example_sales`   
  WHERE `id_customer` = 1
 HAVING `date` BETWEEN @first AND @last 
 ORDER BY `date`;

当你有足够的信心这样做时

SELECT SUM( `profits` ), DATE( `ts` ) AS `date`
  FROM `example_sales`   
  WHERE `id_customer` = 1
 HAVING `date` BETWEEN @first AND @last;

希望这一次能解决问题。

于 2019-01-06T14:13:27.660 回答
0

感谢你们俩的贡献。我已经花了几个小时研究这个问题,其中一些最有希望的答案来自 stackoverflow,这就是为什么我想在这里发布我的问题。

我同意这个问题是不正确的,因为花了很多时间试图定义这个问题。因此,我将把问题变成容易解决的问题。

我将按日历月运行,而不是依赖订阅日期。这种力量在其他地方发生了变化,但我认为我可以接受它们。

再次感谢

于 2019-01-06T15:20:46.827 回答