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的回答似乎更“优雅”,所以我不能保证他和你的解决方案之间的性能权衡。也许你可以评论一下?