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 |