我需要帮助调整此查询,连续超过30天。例如,今天总计+ 29天,比昨天+前天29天等等......
以下是我今天+过去29天所得到的:
SELECT sum(revenue) as total_revenue
FROM sales
WHERE date > UNIX_TIMESTAMP() - (60 * 60 * 24 * 30)
谢谢,
答案 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-subquery
和sub-query and JOIN
如果我有错误,请告诉我。
Q1(相关子查询)和Q2(子查询和JOIN)都返回相同的结果。你可以在这里测试一下http://www.sqlfiddle.com/#!2/e66a9/6
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)
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永远不会停止:-(我已经在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)
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)
+----+--------------------+-------+-------+---------------+-------------+---------+------+--------+-------------------------------------------+
| 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 |
+----+--------------------+-------+-------+---------------+-------------+---------+------+--------+-------------------------------------------+
+----+-------------+------------+-------+---------------+-------------+---------+------+--------+----------------------------------------------+
| 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 |
+----+-------------+------------+-------+---------------+-------------+---------+------+--------+----------------------------------------------+
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;