如何有效地计算每月第n天以来的销售额?

of1yzvn4  于 2021-06-15  发布在  Mysql
关注(0)|答案(3)|浏览(453)

我有一个最新的mysql数据库安装,我需要一个函数来计算上个月的第n个月和今天之间的销售。这个函数每天会被调用几次,因为我在寻找自上个月第n个月以来的累计销售额超过阈值的点。
背景是,我正在开发一个订阅网站。客户将在一年中的特定日期注册,并在全年进行购买。我想能够计算出这个月迄今为止的销售额。
如果一个客户在这个月的第n个月注册,那么我需要计算从这个月的前n个月到今天的销售额。
如果客户在28日注册,而今天是30日,那么你会认为只有2天的销售,但如果今天是3月30日,那么已经30天了。再举一个例子:如果客户在10月31日注册,那么这将如何处理2月28日或4月30日?
我看过timestampdiff()之类的函数,但没有找到一个实用的解决方案。我的意思是一个将做的工作,可以做的任务效率不需要花费太多的cpu周期。
谢谢期待

4szc88ey

4szc88ey1#

我可以推荐时间戳和间隔。它既简单又高效,无需尝试做一些足够琐碎的事情
因此,请考虑以下模式和查询

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;

希望这次能成功。

fiei3ece

fiei3ece2#

您可能正在寻找以下内容:

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

给你几天时间 N ,它返回 N 上个月的第天。
从今天起,如果给予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))
)

yieds公司: '2018-02-28' -(二月最后一天)。

0lvr5msh

0lvr5msh3#

感谢你们两位的贡献。我已经花了几个小时研究这个问题,一些最有希望的答案来自stackoverflow,这就是为什么我想把我的问题贴在这里。
我同意这个问题是错误的,因为我花了相当多的时间来定义这个问题。因此,我要把这个问题变成一个很容易解决的问题。
而不是依赖于订阅日期,我将在日历月的基础上运行。这迫使其他地方发生变化,但我想我可以接受它们。
再次感谢

相关问题