计算每日平均值(或:日期范围内有多少个星期一?)

时间:2012-02-29 00:34:27

标签: mysql sql datetime

我的MySQL表格包含以下列:datetime,price_paid。 我正在尝试计算一周中每天的平均销售额,介于两个日期之间。 这意味着我需要在按工作日分组的日期startDate和endDate之间选择销售总额,并将其除以每个工作日在该范围内发生的次数。

我得到了第一部分:

SELECT DATE_FORMAT(datetime, '%a') AS field1, 
round(SUM(price_paid)/ THEVALUEIMLOOKINGFOR ) AS field2 
FROM Bills 
WHERE date(datetime) BETWEEN '2012-01-02' AND '2012-01-09' 
GROUP BY weekday(datetime)

我没有的是缺失值:我应该除以的数字 - 每天出现在该范围内的次数。我尝试了几种解决方案,但无济于事。

有人可以帮我完成我的SQL语句吗?

谢谢你的时间!

4 个答案:

答案 0 :(得分:8)

也许我太简单了,但考虑到你已经在工作日进行分组,那么每个工作日不会只计算(*)计算该范围内给定工作日的数量吗?

这样:

SELECT DATE_FORMAT(datetime, '%a') AS field1, 
round(SUM(price_paid)/ COUNT(DISTINCT(date(datetime))) ) AS field2 
FROM Bills 
WHERE date(datetime) BETWEEN '2012-01-02' AND '2012-01-09' 
GROUP BY weekday(datetime)

编辑所以不要在同一天多次超额计算(感谢DRapp)

答案 1 :(得分:2)

我知道这是旧的,但“似乎有效”。还不够好。 事实上,如果有一天有ZERO交易,它将计算周一的数量。

有一个公式可以计算日期范围内的星期几。您需要从一周中的已知日期开始。 “1970-01-05”是一个星期一。

以下是您可以使用的功能:

create function CountDaysOfWeek(
    DateFrom DATETIME,
    DateTo DATETIME,
    DayOfWeek int
)
RETURNS int
return FLOOR(DATEDIFF(DateTo,'1970-01-03' + INTERVAL DayOfWeek DAY)/7) - 
   FLOOR(DATEDIFF(DateFrom,'1970-01-03' + INTERVAL (DayOfWeek+1) DAY)/7);

答案 2 :(得分:0)

这是一个名为MakeDateList的存储函数:

DELIMITER $$
DROP FUNCTION IF EXISTS `junk`.`MakeDateList` $$

CREATE FUNCTION `junk`.`MakeDateList`
(
  BeginDate DATE,
  EndDate DATE,
  InclusionList VARCHAR(20)
)

RETURNS VARCHAR(4096)
DETERMINISTIC
BEGIN
  DECLARE RunningDate DATE;
  DECLARE rv VARCHAR(4096);
  DECLARE comma CHAR(1);
  DECLARE IncList,DOWValue VARCHAR(20);
  DECLARE OK_To_Add INT;

  SET IncList = CONCAT(',',InclusionList,',');
  SET comma = '';
  SET rv = '';
  SET RunningDate = BeginDate;

  WHILE RunningDate <= EndDate DO
    SET OK_To_Add = 0;
    SET DOWValue = CONCAT(',',DAYOFWEEK(RunningDate),',');
    IF LOCATE(DOWValue,IncList) > 0 THEN
      SET OK_To_Add = 1;
    END IF;
    IF OK_To_Add = 1 THEN
       SET rv = CONCAT(rv,comma,RunningDate);
    END IF;
    SET comma = ',';
    SET RunningDate = RunningDate + INTERVAL 1 DAY;
  END WHILE;
RETURN rv;
END $$
DELIMITER ;

它有三个参数:BeginDate,EndDate和InclusionList

InclusionList是逗号拼写的数字列表(有效数字1-7)

1 = Sunday
2 = Monday
3 = Tuesday
4 = Wednesday
5 = Thursday
6 = Friday
7 = Saturday

所以要获得星期一,请制作InclusionList 2

示例:调用MakeDateList('2011-10-01','2011-10-01','2')应该为您提供2011年10月全月的星期一

答案 3 :(得分:0)

由于您需要平均值之和,因此需要使用子查询来计算每天的平均值,然后计算平均值的总和。

我修改了查询以包含一个外部查询,该查询返回平均值的总和。但是现在field1将不再有意义,因为它可以是任何日期,具体取决于您使用的订购选项

SELECT field1, SUM (field2) FROM (
  SELECT DATE_FORMAT(datetime, '%a') AS field1, 
  AVG(price_paid) AS field2 
  FROM Bills 
  WHERE date(datetime) BETWEEN '2012-01-02' AND '2012-01-09' 
  GROUP BY weekday(datetime)
)