【发布时间】:2012-01-30 18:23:13
【问题描述】:
我有一个看起来像这样的表:
DataTable
+------------+------------+------------+
| Date | DailyData1 | DailyData2 |
+------------+------------+------------+
| 2012-01-23 | 146.30 | 212.45 |
| 2012-01-20 | 554.62 | 539.11 |
| 2012-01-19 | 710.69 | 536.35 |
+------------+------------+------------+
我正在尝试创建一个视图(称为AggregateView),它将针对每个日期和每个数据列显示几个不同的聚合。例如,select * from AggregateView where Date = '2012-01-23' 可能会给出:
+------------+--------------+----------------+--------------+----------------+
| Date | Data1_MTDAvg | Data1_20DayAvg | Data2_MTDAvg | Data2_20DayAvg |
+------------+--------------+----------------+--------------+----------------+
| 2012-01-23 | 697.71 | 566.34 | 601.37 | 192.13 |
+------------+--------------+----------------+--------------+----------------+
其中Data1_MTDAvg 显示 1 月 23 日之前的每个日期的 avg(DailyData1),Data1_20DayAvg 显示相同但表中前 20 个日期。我不是 SQL 忍者,但我认为最好的方法是通过子查询。 MTD 平均值很简单:
select t1.Date, (select avg(t2.DailyData1)
from DataTable t2
where t2.Date <= t1.Date
and month(t2.Date) = month(t1.Date)
and year(t2.Date) = year(t1.Date)) Data1_MTDAvg
from DataTable t1;
但由于需要限制返回结果的数量,我对 20 天的平均值感到困惑。请注意,表中的日期是不规则的,所以我不能使用日期间隔;我需要表中的最后二十条记录,而不是过去二十天的所有记录。我找到的唯一解决方案是使用嵌套子查询首先限制所选记录,然后取平均值。
单独的子查询适用于单独的硬编码日期:
select avg(t2.DailyData1) Data1_20DayAvg
from (select DailyData1
from DataTable
where Date <= '2012-01-23'
order by Date desc
limit 0,20) t2;
但试图将其作为更大查询的一部分嵌入会失败:
select t1.Date, (select avg(t2.DailyData1) Data1_20DayAvg
from (select DailyData1
from DataTable
where Date <= t1.Date
order by Date desc
limit 0,20) t2)
from DataTable t1;
ERROR 1054 (42S22): Unknown column 't1.Date' in 'where clause'
通过四处搜索,我得到的印象是您不能将相关子查询用作from 子句的一部分,我认为这就是问题所在。另一个问题是我不确定 MySQL 是否会接受在子查询中包含 from 子句的视图定义。为了解决这两个问题,有没有办法限制我的聚合选择中的数据而不诉诸子查询?
【问题讨论】:
标签: mysql sql correlated-subquery