如何连续过去30天?

时间:2013-12-20 02:43:48

标签: mysql sum

我需要帮助调整此查询,连续超过30天。例如,今天总​​计+ 29天,比昨天+前天29天等等......

以下是我今天+过去29天所得到的:

SELECT sum(revenue) as total_revenue
FROM sales
WHERE date > UNIX_TIMESTAMP() - (60 * 60 * 24 * 30)

谢谢,

2 个答案:

答案 0 :(得分:3)

如果你想要一个30天的移动平均线,这里有一种使用相关子查询的方法:

select date,
       (select sum(revenue)
        from sales s2
        where datediff(s2.date, s.date) between 0 and 30
       ) revenue_30days
from sales s;

答案 1 :(得分:1)

你可以尝试一下吗?我认为相关的子查询很慢......

SELECT s1.date, SUM(s2.revenue)
FROM (
    SELECT date
    FROM sales
    GROUP BY date
) s1 INNER JOIN (
    SELECT date, SUM(revenue) AS revenue
    FROM sales
    GROUP BY date
) s2
WHERE s2.date BETWEEN s1.date AND s1.date + INTERVAL 30 DAY AND s1.date
GROUP BY s1.date;

性能测试

我测试了correlated sub-subquerysub-query and JOIN 如果我有错误,请告诉我。

Q1(相关子查询)和Q2(子查询和JOIN)都返回相同的结果。你可以在这里测试一下http://www.sqlfiddle.com/#!2/e66a9/6

摘要

  • Q1(相关子查询): 1小时28分33.67秒
  • Q2(子查询和加入): 0.14秒

测试环境

  • MySQL 5.5
  • CentOS 5.3 64位
  • TPC-H orders表(包含3M行)

模式

CREATE TABLE `orders` (
  `o_orderkey` int(11) NOT NULL,
  `o_custkey` int(11) NOT NULL,
  `o_orderstatus` char(1) NOT NULL,
  `o_totalprice` decimal(15,2) NOT NULL,
  `o_orderDATE` date NOT NULL,
  `o_orderpriority` char(15) NOT NULL,
  `o_clerk` char(15) NOT NULL,
  `o_shippriority` int(11) NOT NULL,
  `o_comment` varchar(79) NOT NULL,
  PRIMARY KEY (`o_orderkey`),
  KEY `o_custkey` (`o_custkey`),
  KEY `o_orderDATE` (`o_orderDATE`),
  CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`o_custkey`) REFERENCES `customer` (`c_custkey`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

总计数

mysql> SELECT SQL_NO_CACHE COUNT(*) FROM orders;
+----------+
| COUNT(*) |
+----------+
|  3000000 |
+----------+
1 row in set (0.51 sec)

1992-02-01和1992-01-31之间的行COUNT

mysql> SELECT COUNT(*) FROM orders o WHERE o.o_orderDATE BETWEEN '1992-01-01' AND '1992-01-31';
+----------+
| COUNT(*) |
+----------+
|    38618 |
+----------+
1 row in set (0.01 sec)

Q1(1小时28分33.67秒)

不幸的是Q1永远不会停止:-(我已经在10分钟后杀了它我在见面后得到了结果。花了1小时28分

SELECT SQL_NO_CACHE DISTINCT o_orderDATE,
       (SELECT SUM(o_totalprice)
        FROM orders o2
        WHERE DATEDIFF(o2.o_orderDATE, o.o_orderDATE) BETWEEN 0 AND 29
          AND o2.o_orderDATE BETWEEN '1992-01-01' AND '1992-03-01'
       ) revenue_30days
FROM orders o
WHERE o.o_orderDATE BETWEEN '1992-01-01' AND '1992-01-31';

+-------------+----------------+
| o_orderDATE | revenue_30days |
+-------------+----------------+
| 1992-01-01  |  5648795149.74 |
| 1992-01-02  |  5649262055.28 |
| 1992-01-03  |  5666711554.48 |
| 1992-01-04  |  5677697387.74 |
| 1992-01-05  |  5676650777.36 |
| 1992-01-06  |  5669275725.69 |
| 1992-01-07  |  5692730838.47 |
| 1992-01-08  |  5688570035.24 |
| 1992-01-09  |  5684709644.40 |
| 1992-01-10  |  5688857031.75 |
| 1992-01-11  |  5676182193.32 |
| 1992-01-12  |  5683115775.20 |
| 1992-01-13  |  5670141469.02 |
| 1992-01-14  |  5684636532.16 |
| 1992-01-15  |  5683027972.67 |
| 1992-01-16  |  5670511926.85 |
| 1992-01-17  |  5674076998.82 |
| 1992-01-18  |  5668348303.38 |
| 1992-01-19  |  5674735578.96 |
| 1992-01-20  |  5689425729.08 |
| 1992-01-21  |  5686550437.68 |
| 1992-01-22  |  5684366682.26 |
| 1992-01-23  |  5679647411.20 |
| 1992-01-24  |  5676757491.15 |
| 1992-01-25  |  5679641366.53 |
| 1992-01-26  |  5685238563.41 |
| 1992-01-27  |  5691828747.39 |
| 1992-01-28  |  5695307116.83 |
| 1992-01-29  |  5687069527.23 |
| 1992-01-30  |  5683190558.58 |
| 1992-01-31  |  5686476320.12 |
+-------------+----------------+
31 rows in set (1 hour 28 min 33.67 sec)

Q2(0.01秒)

SELECT SQL_NO_CACHE o1.o_orderDATE, SUM(o2.o_totalprice)
FROM (
    SELECT o_orderDATE
    FROM orders
    WHERE o_orderDATE BETWEEN '1992-01-01' AND '1992-01-31'
    GROUP BY o_orderDATE
) o1 INNER JOIN (
    SELECT o_orderDATE, SUM(o_totalprice) AS o_totalprice
    FROM orders
    WHERE o_orderDATE BETWEEN '1992-01-01' AND '1992-03-01'
    GROUP BY o_orderDATE
) o2
WHERE o2.o_orderDATE BETWEEN o1.o_orderDATE AND o1.o_orderDATE + INTERVAL 29 DAY AND o1.o_orderDATE
GROUP BY o1.o_orderDATE;
+-------------+----------------------+
| o_orderDATE | SUM(o2.o_totalprice) |
+-------------+----------------------+
| 1992-01-01  |        5648795149.74 |
| 1992-01-02  |        5649262055.28 |
| 1992-01-03  |        5666711554.48 |
| 1992-01-04  |        5677697387.74 |
| 1992-01-05  |        5676650777.36 |
| 1992-01-06  |        5669275725.69 |
| 1992-01-07  |        5692730838.47 |
| 1992-01-08  |        5688570035.24 |
| 1992-01-09  |        5684709644.40 |
| 1992-01-10  |        5688857031.75 |
| 1992-01-11  |        5676182193.32 |
| 1992-01-12  |        5683115775.20 |
| 1992-01-13  |        5670141469.02 |
| 1992-01-14  |        5684636532.16 |
| 1992-01-15  |        5683027972.67 |
| 1992-01-16  |        5670511926.85 |
| 1992-01-17  |        5674076998.82 |
| 1992-01-18  |        5668348303.38 |
| 1992-01-19  |        5674735578.96 |
| 1992-01-20  |        5689425729.08 |
| 1992-01-21  |        5686550437.68 |
| 1992-01-22  |        5684366682.26 |
| 1992-01-23  |        5679647411.20 |
| 1992-01-24  |        5676757491.15 |
| 1992-01-25  |        5679641366.53 |
| 1992-01-26  |        5685238563.41 |
| 1992-01-27  |        5691828747.39 |
| 1992-01-28  |        5695307116.83 |
| 1992-01-29  |        5687069527.23 |
| 1992-01-30  |        5683190558.58 |
| 1992-01-31  |        5686476320.12 |
+-------------+----------------------+
31 rows in set (0.14 sec)

Q1的解释

+----+--------------------+-------+-------+---------------+-------------+---------+------+--------+-------------------------------------------+
| id | select_type        | table | type  | possible_keys | key         | key_len | ref  | rows   | Extra                                     |
+----+--------------------+-------+-------+---------------+-------------+---------+------+--------+-------------------------------------------+
|  1 | PRIMARY            | o     | range | o_orderDATE   | o_orderDATE | 3       | NULL |  75702 | Using where; Using index; Using temporary |
|  2 | DEPENDENT SUBQUERY | o2    | range | o_orderDATE   | o_orderDATE | 3       | NULL | 147522 | Using where                               |
+----+--------------------+-------+-------+---------------+-------------+---------+------+--------+-------------------------------------------+

Q2的解释

+----+-------------+------------+-------+---------------+-------------+---------+------+--------+----------------------------------------------+
| id | select_type | table      | type  | possible_keys | key         | key_len | ref  | rows   | Extra                                        |
+----+-------------+------------+-------+---------------+-------------+---------+------+--------+----------------------------------------------+
|  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL        | NULL    | NULL |     31 | Using where; Using temporary; Using filesort |
|  1 | PRIMARY     | <derived3> | ALL   | NULL          | NULL        | NULL    | NULL |     61 | Using where; Using join buffer               |
|  3 | DERIVED     | orders     | range | o_orderDATE   | o_orderDATE | 3       | NULL | 147522 | Using where                                  |
|  2 | DERIVED     | orders     | range | o_orderDATE   | o_orderDATE | 3       | NULL |      5 | Using where; Using index for group-by        |
+----+-------------+------------+-------+---------------+-------------+---------+------+--------+----------------------------------------------+

Q2整行(8.87秒)

SELECT SQL_NO_CACHE o1.o_orderDATE, SUM(o2.o_totalprice)
FROM (
    SELECT o_orderDATE
    FROM orders
    GROUP BY o_orderDATE
) o1 INNER JOIN (
    SELECT o_orderDATE, SUM(o_totalprice) AS o_totalprice
    FROM orders
    GROUP BY o_orderDATE
) o2
GROUP BY o1.o_orderDATE;