MySQL按日期求和值,将今年与去年进行比较
假设我有一张满是订单的桌子。每天可以有多个订单,总金额不同:MySQL按日期求和值,将今年与去年进行比较,mysql,Mysql,假设我有一张满是订单的桌子。每天可以有多个订单,总金额不同: # Create orders table CREATE TABLE orders ( `id` int(11) NOT NULL AUTO_INCREMENT, `order_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `total` decimal(9,2) DEFAULT NULL, PRIMARY KEY (`id`) ); 我想为这个表创建一组随机测
# Create orders table
CREATE TABLE orders (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`total` decimal(9,2) DEFAULT NULL,
PRIMARY KEY (`id`)
);
我想为这个表创建一组随机测试数据,所以我创建了一个存储过程:
# Create test data for orders table
DELIMITER $$
CREATE PROCEDURE prepare_orders_data()
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE j INT DEFAULT FLOOR(RAND() * 10 + 1); # Number of order entries in one day
# randomized between 1 and 10 days
# Create 2 years worth of data from 2014-01-01 to 2015-12-31
WHILE i < (365*2) DO
WHILE j > 0 DO
INSERT INTO orders(order_date, total)
VALUES (DATE_ADD('2014-01-01', INTERVAL 1*i DAY), RAND() * 100);
SET j = j - 1;
END WHILE;
SET j = FLOOR(RAND() * 10 + 1); #Random number of days from 1-10
SET i = i + 1;
END WHILE;
END$$
DELIMITER ;
CALL prepare_orders_tlano_data();
+--------------+--------------+----------+---------------+---------------+
| ThisYearDate | LastYearDate | DayName | ThisYearTotal | LastYearTotal |
+--------------+--------------+----------+---------------+---------------+
| 2015-01-01 | 2014-01-02 | Thursday | 363.56 | 11.26 |
| 2015-01-02 | 2014-01-03 | Friday | 137.62 | 189.76 |
| 2015-01-03 | 2014-01-04 | Saturday | 399.40 | 257.42 |
| 2015-01-04 | 2014-01-05 | Sunday | 502.80 | 336.38 |
| 2015-01-05 | 2014-01-06 | Monday | 107.59 | 466.79 |
+--------------+--------------+----------+---------------+---------------+
下面是一个返回结果的示例(由于存储过程中的随机数据,结果会有所不同):
有人能想出一种不同的方法来实现这一点吗
编辑:我查看了@Used\u By\u ready的解决方案,并将其重写了一点,以使其输出与我的表相同:
SELECT
(CASE WHEN order_date < '2014-12-31'
THEN DATE_ADD(order_date, INTERVAL 52 WEEK)
ELSE order_date END) as ThisYearOrderDate,
(CASE WHEN order_date < '2014-12-31'
THEN order_date
ELSE DATE_ADD(order_date, INTERVAL -52 WEEK) END) as LastYearOrderDate,
DAYNAME(order_date) DayName,
SUM(CASE WHEN order_date >= '2014-12-31'
THEN total ELSE 0 END) as ThisYearTotal,
SUM(CASE WHEN order_date < '2014-12-31'
THEN total ELSE 0 END) as LastYearTotal
FROM orders
GROUP BY ThisYearOrderDate;
对日期和分组使用case表达式,并对两个和使用类似的case表达式(条件聚合) 查询1:
select
case when order_date < '2015-01-01'
then order_date + INTERVAL '52 WEEKS'
else order_date
end as an_order_date_pair
, SUM(case when order_date < '2015-01-01'
then total else 0
end) as prev_yr
, SUM(case when order_date >= '2015-01-01'
then total else 0
end) as this_yr
from orders
group by
case when order_date < '2015-01-01'
then order_date + INTERVAL '52 WEEKS'
else order_date
end
| an_order_date_pair | prev_yr | this_yr |
|---------------------------|---------|---------|
| January, 01 2015 00:00:00 | 11.26 | 363.56 |
| January, 05 2015 00:00:00 | 466.79 | 107.59 |
| January, 02 2015 00:00:00 | 189.76 | 137.62 |
| January, 04 2015 00:00:00 | 336.38 | 502.8 |
| January, 03 2015 00:00:00 | 257.42 | 399.4 |
是的,我的方法限制在52周内。顺便说一句:少于2015-01-01将使日期与您在第一个预期结果中的日期一致。感谢您的回复。您的解决方案确实运行得更快,但我在上面的编辑中指定了一些问题。
select
case when order_date < '2016-01-01' then order_date + INTERVAL 52 WEEKS else order_date end as an_order_date_pair
, SUM(case then order_date < '2016-01-01' then total end) as prev_yr
, SUM(case then order_date >= '2016-01-01' then total end) as this_yr
from orders
group by
case when order_date < '2016-01-01' then order_date + INTERVAL 52 WEEKS else order_date end
CREATE TABLE Orders
(order_date timestamp , total decimal(12,3))
;
INSERT INTO Orders
(order_date, total)
VALUES
('2014-01-02 00:00:00', 11.26),
('2014-01-03 00:00:00', 189.76),
('2014-01-04 00:00:00', 257.42),
('2014-01-05 00:00:00', 336.38),
('2014-01-06 00:00:00', 466.79),
('2015-01-01 00:00:00', 363.56),
('2015-01-02 00:00:00', 137.62),
('2015-01-03 00:00:00', 399.40),
('2015-01-04 00:00:00', 502.80),
('2015-01-05 00:00:00', 107.59)
;
select
case when order_date < '2015-01-01'
then order_date + INTERVAL '52 WEEKS'
else order_date
end as an_order_date_pair
, SUM(case when order_date < '2015-01-01'
then total else 0
end) as prev_yr
, SUM(case when order_date >= '2015-01-01'
then total else 0
end) as this_yr
from orders
group by
case when order_date < '2015-01-01'
then order_date + INTERVAL '52 WEEKS'
else order_date
end
| an_order_date_pair | prev_yr | this_yr |
|---------------------------|---------|---------|
| January, 01 2015 00:00:00 | 11.26 | 363.56 |
| January, 05 2015 00:00:00 | 466.79 | 107.59 |
| January, 02 2015 00:00:00 | 189.76 | 137.62 |
| January, 04 2015 00:00:00 | 336.38 | 502.8 |
| January, 03 2015 00:00:00 | 257.42 | 399.4 |