几年前,我有大量带有事务日期时间字段的记录。我想对今年和去年相同的时间跨度做一个比较分析。如何在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等?
到目前为止,我的查询如下:
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;本质上,我希望实现以下伪查询的东西:
GROUP BY
STARTING FROM THE OLDEST DATE (A.transaction_date + INTERVAL 6 DAY)发布于 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中,所以现在您的记录将显示每个客户级别、每个产品和燃料类型,以及今年和去年之间的销售额和数量。
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_namehttps://stackoverflow.com/questions/9809054
复制相似问题