【问题标题】:MySQL : weekly and monthly averageMySQL:每周和每月平均
【发布时间】:2016-03-15 07:41:39
【问题描述】:

这是我的bill表:

shop_id | billing_date | total
------------------------------
ABC     | 2016-03-07   | 100
ABC     | 2016-03-14   | 200
DEF     | 2016-03-07   | 300
DEF     | 2016-03-14   | 100
GHI     | 2016-03-07   | 30

我希望每家商店有一条线,每周平均总数当月总数每月平均总数 .最终数据必须如下所示:

shop | weekly avg. | current month total | monthly avg.
-------------------------------------------------------
ABC  | 150         | 300                 | 300
DEF  | 200         | 500                 | 500
GHI  | 30          | 30                  | 30

我的问题是:是否可以直接从 SQL 查询中获取这些信息?

【问题讨论】:

  • 是的,到目前为止您尝试过什么?请随时与我们分享。
  • 我尝试过像这样按周分组:SELECT shop_id, avg(total) as week_avg FROM bill b GROUP BY shop_id, WEEKOFYEAR(billing_date);但我离解决方案还很远。我想我必须进行子查询,但不知道如何...
  • 按周的 AVG 和按月的 AVG 之间存在矛盾,因为它位于一个结果行中 - 应该是哪一周?为什么ABC的月平均AVG是300——这家店的SUM和AVG有什么区别?
  • @mitkosoft 我的样本数据可能并不重要,因为这里只有一个月。对于每家商店,我想知道每周和每月的平均销售量。如果一家商店一月份总共赚了 500 美元,二月份总共赚了 300 美元,那么每月平均应该是 400 美元。希望我回答了你的问题,我的英语很差...
  • 按月计算的 AVG 很清楚,按周计算的 AVG 是个问题 - 你想要什么作为最终结果?

标签: mysql sql database


【解决方案1】:

嘿,您可以使用 mysql 的 WEEKMONTH 在当年尝试这种方式。根据您在表格中的数据条目是按周计算的:

SQLFIDDLE

select shop_id,(sum(total)/(WEEK(MAX(bdate)) - WEEK(MIN(bdate))+1)) as weekly_avg,(sum(total)/(MONTH(MAX(bdate))-MONTH(MIN(bdate))+1)) as mothly_avg, sum( case when MONTH(bdate) = MONTH(NOW()) then total else 0 end) as current_month_total  from bill group by shop_id WHERE YEAR(bdate) = 2016

大于一年的年数

SQL FIDDLE

select shop_id,
sum(total)/(12 * (YEAR(MAX(bdate)) - YEAR(MIN(bdate))) + (MONTH(MAX(bdate)) - MONTH(MIN(bdate)))+1) as month_avg,
sum(total)/(7 * (YEAR(MAX(bdate)) - YEAR(MIN(bdate))) + (WEEK(MAX(bdate)) - WEEK(MIN(bdate)))+1) as weekly_avg,
sum( case when YEAR(bdate) = YEAR(bdate) and MONTH(bdate) = MONTH(NOW()) then total else 0 end) as current_month_total from bill group by shop_id

【讨论】:

  • 嘿,我刚刚快速测试了它,结果看起来不错:)我将在今天晚些时候实现它,我会告诉你;)非常感谢!
  • 当日期范围超过一年时,这可能会产生意想不到的结果
  • @LuisSiquot 我已经在当年的where 子句中放置了当年的过滤器
  • 这种查询只对一年内的数据有效?如果我想根据多年的销售额按月计算 AVG,该怎么办?
  • @VishalJAIN 成功了!!你太棒了;)
【解决方案2】:

这是你追求的那种东西吗??:

SELECT DISTINCT(bill.shop_id),wk as WeeklyTotal,mt as MonthlyTotal,ma as MonthlyAverage
FROM bill
JOIN (SELECT AVG(total) wk,shop_id
    FROM bill
    WHERE YEAR(billing_date) = 2016 AND MONTH(billing_date) = 1
    GROUP BY shop_id) as weekly ON bill.shop_id = weekly.shop_id
JOIN (SELECT SUM(total) mt,shop_id
    FROM bill
    WHERE YEAR(billing_date) = 2016 AND MONTH(billing_date) = 1
    GROUP BY CONCAT(shop_id,MONTH(billing_date))
    ) month_total ON month_total.shop_id = bill.shop_id
JOIN (SELECT AVG(total) ma,shop_id
    FROM bill
    WHERE YEAR(billing_date) = 2016 AND MONTH(billing_date) = 1
    GROUP BY CONCAT(shop_id,MONTH(billing_date))
) month_avg ON month_avg.shop_id = bill.shop_id

【讨论】:

  • 不,此查询返回每个商店的多行;)
  • 我收到此消息:字段列表中的列“shop_id”不明确(我使用 Doctrine 2 原始查询)
  • 很抱歉,这个查询仍然返回每个商店的多行:(
  • 我预计它会返回多个月 - 试试看。
  • 好的,结果看起来不错,但与评分最高的答案有很大的不同。我会在少量数据上尝试一下,然后让你知道;)谢谢老兄!
【解决方案3】:

您可以使用条件聚合和条件逻辑来做到这一点:

select shop_id,
       sum(total) / (7 * datediff(max(billing_date), min(billing_date)) + 1) as avg_weekly,
       sum(case when year(billing_date) = year(now()) and month(billing_date) = month(now()) then total else 0 end) as curr_Month,
       (sum(total) /
        (year(max(billing_date)) * 12 + month(max(billing_date)) - 
         year(min(billing_date)) * 12 + month(min(billing_date))
             ) + 1
        )
       ) as avg_month
total else 0 end) as week_total
from bill
gropu by shop_id;

【讨论】:

  • 这个查询有问题,括号有问题,但我找不到问题出在哪里......
猜你喜欢
  • 1970-01-01
  • 2018-12-19
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 2017-11-12
  • 2018-12-14
  • 1970-01-01
  • 2017-04-17
相关资源
最近更新 更多