SQL(MySQL)查询,用于在多个时间范围内提取聚合
假设我有下表,我的表:SQL(MySQL)查询,用于在多个时间范围内提取聚合,mysql,sql,aggregate-functions,Mysql,Sql,Aggregate Functions,假设我有下表,我的表: +----------+------------+------------+ + key_code + cost_value + cost_date + +----------+------------+------------+ + AAAA + 1.01 + 2015-01-05 + + AAAA + 4.04 + 2015-01-10 + + AAAA + 3.03 + 2015-01-15 + +
+----------+------------+------------+
+ key_code + cost_value + cost_date +
+----------+------------+------------+
+ AAAA + 1.01 + 2015-01-05 +
+ AAAA + 4.04 + 2015-01-10 +
+ AAAA + 3.03 + 2015-01-15 +
+ AAAA + 2.02 + 2015-01-20 +
+ BBBB + 5.05 + 2015-01-05 +
+ BBBB + 8.08 + 2015-01-10 +
+ BBBB + 7.07 + 2015-01-15 +
+ BBBB + 6.06 + 2015-01-20 +
+----------+------------+------------+
我可以通过以下查询提取每个关键代码的最小和最大成本值:
SELECT key_code, MIN(cost_value) AS cost_min, MAX(cost_value) AS cost_max
FROM my_table
GROUP BY key_code
ORDER BY key_code;
+----------+----------+----------+
+ key_code + cost_min + cost_max +
+----------+----------+----------+
+ AAAA + 1.01 + 4.04 +
+ BBBB + 5.05 + 8.08 +
+----------+----------+----------+
SELECT key_code, MIN(cost_value) AS cost_min_07, MAX(cost_value) AS cost_max_07
FROM my_table
WHERE cost_date >= (CURDATE() - INTERVAL 7 DAY)
GROUP BY key_code
ORDER BY key_code;
+----------+-------------+-------------+
+ key_code + cost_min_07 + cost_max_07 +
+----------+-------------+-------------+
+ AAAA + 2.02 + 3.03 +
+ BBBB + 6.06 + 7.07 +
+----------+-------------+-------------+
我可以通过以下查询将过去7天(假设今天=2015-01-21)的最小/最大值限制为成本_值:
SELECT key_code, MIN(cost_value) AS cost_min, MAX(cost_value) AS cost_max
FROM my_table
GROUP BY key_code
ORDER BY key_code;
+----------+----------+----------+
+ key_code + cost_min + cost_max +
+----------+----------+----------+
+ AAAA + 1.01 + 4.04 +
+ BBBB + 5.05 + 8.08 +
+----------+----------+----------+
SELECT key_code, MIN(cost_value) AS cost_min_07, MAX(cost_value) AS cost_max_07
FROM my_table
WHERE cost_date >= (CURDATE() - INTERVAL 7 DAY)
GROUP BY key_code
ORDER BY key_code;
+----------+-------------+-------------+
+ key_code + cost_min_07 + cost_max_07 +
+----------+-------------+-------------+
+ AAAA + 2.02 + 3.03 +
+ BBBB + 6.06 + 7.07 +
+----------+-------------+-------------+
但是,如果我想同时提取前7天、14天和21天的min/max,该怎么办?如何(最有效地)生成以下结果?我想我是在问如何对每个MIN()和MAX()对应用不同的WHERE
您可以按键代码和周期对结果进行分组。为了得到合适的周期,我们在
7
的基础上移动日期,假设当前日期()
是周期的结束。试试下面的查询<代码>d_最小值-期间开始,d_最大值
-期间结束,d_差异
-当前日期和期间日期之间的期间差异
set @base=7;
set @v=TO_DAYS(CURRENT_DATE());
set @diff=@base-@v%@base-1;
set @vb=FLOOR((@v+@diff)/@base);
SELECT
FROM_DAYS(t.vb*@base-@diff) AS d_min,
FROM_DAYS((t.vb+1)*@base-@diff-1) AS d_max,
FLOOR(@vb-t.vb) AS d_diff,
t.key_code,
t.cost_min,
t.cost_max
FROM (
SELECT
key_code,
MIN(cost_value) AS cost_min,
MAX(cost_value) AS cost_max,
FLOOR((TO_DAYS(cost_date)+@diff)/@base) as vb
FROM
my_table
GROUP BY
key_code, vb
ORDER BY
vb DESC, key_code
) t;
使用条件聚合:
SELECT key_code,
MIN(CASE WHEN cost_date >= CURDATE() - INTERVAL 7 DAY THEN cost_value END) AS cost_min_07,
MAX(CASE WHEN cost_date >= CURDATE() - INTERVAL 7 DAY THEN cost_value END) AS cost_max_07,
MIN(CASE WHEN cost_date >= CURDATE() - INTERVAL 14 DAY THEN cost_value END) AS cost_min_14,
MAX(CASE WHEN cost_date >= CURDATE() - INTERVAL 14 DAY THEN cost_value END) AS cost_max_14,
MIN(CASE WHEN cost_date >= CURDATE() - INTERVAL 21 DAY THEN cost_value END) AS cost_min_21,
MAX(CASE WHEN cost_date >= CURDATE() - INTERVAL 21 DAY THEN cost_value END) AS cost_max_21
FROM my_table
WHERE cost_date >= (CURDATE() - INTERVAL 21 DAY)
GROUP BY key_code
ORDER BY key_code;
我会研究表别名,但我从未尝试在一条sql语句中执行不同的组。可能会为不同的日期范围创建一些视图,然后将它们组合起来。为了可伸缩性,您可能更喜欢将结果按行显示,而不是按列显示,然后在演示层中处理格式设置。库,Gordon-工作完美,代码看起来“优雅”。我以前从未见过案例构造-有时知道要寻找什么会有所帮助!谢谢,Max。我没有尝试你的代码,因为Gordon的回答似乎更“优雅”,所以我不能保证他和你的解决方案之间的性能权衡。也许你可以评论一下?