パズルとして、これは解決策です...実際には、データの性質によってはひどく実行される場合があります。いずれにせよ、インデックスに注意してください。
create database tmp;
create table t (value float, dt date); -- if you use int, you need to care about rounding
insert into t values (10, '2012-10-30'), (15, '2012-10-29'), (null, '2012-10-28'), (null, '2012-10-27'), (7, '2012-10-26');
select t1.dt, t1.value, t2.dt, t2.value, count(*) cnt
from t t1, t t2, t t3
where
t2.dt >= t1.dt and t2.value is not null
and not exists (
select *
from t
where t.dt < t2.dt and t.dt >= t1.dt and t.value is not null
)
and t3.dt <= t2.dt
and not exists (
select *
from t where t.dt >= t3.dt and t.dt < t2.dt and t.value is not null
)
group by t1.dt;
+------------+-------+------------+-------+-----+
| dt | value | dt | value | cnt |
+------------+-------+------------+-------+-----+
| 2012-10-26 | 7 | 2012-10-26 | 7 | 1 |
| 2012-10-27 | NULL | 2012-10-29 | 15 | 3 |
| 2012-10-28 | NULL | 2012-10-29 | 15 | 3 |
| 2012-10-29 | 15 | 2012-10-29 | 15 | 3 |
| 2012-10-30 | 10 | 2012-10-30 | 10 | 1 |
+------------+-------+------------+-------+-----+
5 rows in set (0.00 sec)
select dt, value/cnt
from (
select t1.dt , t2.value, count(*) cnt
from t t1, t t2, t t3
where
t2.dt >= t1.dt and t2.value is not null
and not exists (
select *
from t
where t.dt < t2.dt and t.dt >= t1.dt and t.value is not null
)
and t3.dt <= t2.dt
and not exists (
select *
from t
where t.dt >= t3.dt and t.dt < t2.dt and t.value is not null
)
group by t1.dt
) x;
+------------+-----------+
| dt | value/cnt |
+------------+-----------+
| 2012-10-26 | 7 |
| 2012-10-27 | 5 |
| 2012-10-28 | 5 |
| 2012-10-29 | 5 |
| 2012-10-30 | 10 |
+------------+-----------+
5 rows in set (0.00 sec)
説明:
- t1 は元のテーブルです
- t2 は、null 以外の値を持つ最小の日付を持つテーブル内の行です。
- t3 はすべて間にある行なので、他の行でグループ化してカウントできます
申し訳ありませんが、明確にすることはできません。私にとっても紛らわしいです:-)