首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按周分组的MySQL

问按周分组的MySQL
EN

Stack Overflow用户
提问于 2012-03-22 00:42:48
回答 1查看 1.8K关注 0票数 1

几年前,我有大量带有事务日期时间字段的记录。我想对今年和去年相同的时间跨度做一个比较分析。如何在3个月的范围内按周分组?

我在使用YEARWEEK和WEEK函数时遇到了问题,因为2012年的开始日期与2011年的开始日期相比。

假设我有从1月1日到当天每天的日期时间记录,以及前一年的日期时间相同的记录,我如何按周分组,以便输出是日期如下的总和: 01/01/2011,01/08/2011,01/15/2011等,以及01/01/2012,01/08/2012,01/15/2012等?

到目前为止,我的查询如下:

代码语言:javascript
复制
SELECT 
    DATE_FORMAT(A.transaction_date, '%Y-%m-%d') as date,
    ROUND(sum(A.quantity), 3) AS quantity,
    ROUND(sum(A.total_amount), 3) AS amount,
    A.product_code, 
    D.fuel_type_code, 
    D.fuel_type_name, 
    C.customer_code, 
    C.customer_name 
FROM 
    cl_transactions AS A
INNER JOIN 
    card AS B ON A.card_number=B.card_number 
INNER JOIN 
    customer AS C ON B.customer_code=C.customer_code 
INNER JOIN 
    fuel_type AS D ON A.fuel_type=D.fuel_type_code 
WHERE 
    ((A.transaction_date >= DATE_FORMAT(NOW() - INTERVAL 3 MONTH, '%Y-%m-01')) OR (A.transaction_date - INTERVAL 1 YEAR >=  DATE_FORMAT(NOW() - INTERVAL 15 MONTH, '%Y-%m-01') AND A.transaction_date <= NOW() - INTERVAL 1 YEAR))
GROUP BY 
    A.transaction_date, fuel_type_code;

本质上,我希望实现以下伪查询的东西:

代码语言:javascript
复制
GROUP BY 
    STARTING FROM THE OLDEST DATE (A.transaction_date + INTERVAL 6 DAY)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-22 01:25:01

我从一个内部查询开始,使用sqlvariable构建今年和去年的起始/月份/日的起始/终止范围(例如,分别为2012-01-01和2011-01-01 )。在此基础上,我还预先格式化了最终输出的日期,以便您有一个显示的主日期基准,以反映“今年”周的日期。

在此基础上,我连接到transaction表,其中事务日期介于当前周的开始和下周的开始之间。由于日期/时间戳包括小时分钟,因此2012-01-01本身隐含为当天的12:00:00am (午夜)。到7天后的12:00:00该日期将成为下一周的开始日期。

因此,通过加入在过去一年或这一年时间段之间的日期,它是相同的组资格。因此,字段选择分别在去年或今年进行一次舍入( SUM( IF()。如果传入事务处理日期早于本年度的周起始日期,则它必须是上一年的记录,否则为本年度的记录。因此,分别添加值本身,或在应用时添加零。

所以现在,你有了group by。它所限定的周已经通过"ThisYearWeekOf“格式化列从内部查询准备好了,而不管另外计算的"YEARWEEK()”或" week ()“。日期范围为我们解决了这一问题。

最后,我添加了fuel-type作为连接,并将其包含为group by。您必须按所有非聚集列进行分组才能获得正确的SQL,尽管如果在group by中没有指定第一个条目,MySQL只允许获取给定组的第一个条目。

最后,我确实包含了客户的信息,因为您在group by中没有它,并且看起来不适用……它会随意地抓取一个。但是,我已经将其添加到group by中,所以现在您的记录将显示每个客户级别、每个产品和燃料类型,以及今年和去年之间的销售额和数量。

代码语言:javascript
复制
SELECT
      JustWeekRange.ThisYearWeekOf,
      CTrans.product_code,
      FT.fuel_type_code, 
      FT.fuel_type_name, 
      C.customer_code, 
      C.customer_name,
      ROUND( SUM( IF( CTrans.transaction_date < JustWeekRange.ThisYrWeekStart, CTrans.Quantity, 0 )), 3) as LastYrQty,
      ROUND( SUM( IF( CTrans.transaction_date < JustWeekRange.ThisYrWeekStart, CTrans.total_amount, 0 )), 3) as LastYrAmt,
      ROUND( SUM( IF( CTrans.transaction_date < JustWeekRange.ThisYrWeekStart, 0, CTrans.Quantity )), 3) as ThisYrQty,
      ROUND( SUM( IF( CTrans.transaction_date < JustWeekRange.ThisYrWeekStart, 0, CTrans.total_amount )), 3) as ThisYrAmt,
   FROM 
      ( SELECT 
                 DATE_FORMAT(@ThisYearDate, '%Y-%m-%d') as ThisYearWeekOf,
                 @LastYearDate as LastYrWeekStart,
                 @ThisYearDate as ThisYrWeekStart,
                 @LastYearDate := date_add( @LastYearDate, interval 7 day ) LastYrStartOfNextWeek,
                 @ThisYearDate := date_add( @ThisYearDate, interval 7 day ) ThisYrStartOfNextWeek
            FROM 
                 (select @ThisYearDate := '2012-01-01',
                         @LastYearDate := '2011-01-01' ) sqlvars,
                 cl_transactions justForLimit
            HAVING
               ThisYrWeekStart < '2012-04-01'
            LIMIT 15 ) JustWeekRange

      JOIN cl_transactions AS CTrans
         ON    CTrans.transaction_date BETWEEN 
               JustWeekRange.LastYrWeekStart AND JustWeekRange.LastYrStartOfNextWeek
           OR  CTrans.transaction_date BETWEEN 
               JustWeekRange.ThisYrWeekStart AND JustWeekRange.ThisYrStartOfNextWeek

      JOIN fuel_type FT
         ON CTrans.fuel_type = FT.fuel_type_code

      JOIN card 
         ON CTrans.card_number = card.card_number 
         JOIN customer AS C 
            ON card.customer_code = C.customer_code 

   GROUP BY
      JustWeekRange.ThisYearWeekOf,
      CTrans.product_code,
      FT.fuel_type_code, 
      FT.fuel_type_name,
      C.customer_code, 
      C.customer_name
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9809054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档