|
下午的语句经过考虑和测试, 证明有错误.
以下为经过测试的语句.
表结构:
[php]
create table trade_test (
t_date date, -- 时间
t_id varchar2(6), -- 用户
t_c number(5) ) -- 余额
/
[/php]
测试样例:
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 100, 'ABC', 100);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 100 + 1/24, 'ABC', 95);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 90, 'ABC', 90);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 90+ 1/24, 'ABC', 85);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 50, 'ABC', 50);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 30, 'ABC', 30);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 30 + 1/24, 'ABC', 25);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 10, 'ABC', 10);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 1, 'ABC', 5);
---
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 100, 'XYZ', 100);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 100 + 1/24, 'XYZ', 95);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 90, 'XYZ', 90);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 90+ 1/24, 'XYZ', 85);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 50, 'XYZ', 50);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 30, 'XYZ', 30);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 30 + 1/24, 'XYZ', 25);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 10, 'XYZ', 10);
INSERT INTO TRADE_TEST VALUES ( SYSDATE - 1, 'XYZ', 5);
COMMIT;
语句:
[php]
select v_id, to_char(v_date, 'YYYY-MM-DD'), min(v_c)
from
(select v_id, v_date,
NVL(VALL.t_c,
( select t_c
from trade_test A
where A.t_id = VALL.v_id
and t_date =
( select max(t_date)
from trade_test B
where B.t_id = VALL.v_id and B.t_date <=
VALL.v_date
)
)
) v_c
from
(
select vdid.v_date, vdid.v_id, tt.t_c
from (
select distinct vd.v_date, vid.v_id from
( select (sysdate - rownum) v_date
from all_objects where rownum < 101
union select distinct t_date v_date from
trade_test
) vd,
(select distinct t_id v_id from trade_test) vid
) vdid, trade_test tt
where vdid.v_date = tt.t_date(+)
and vdid.v_id = tt.t_id (+)
) VALL
)VMIN
group by v_id, to_char(v_date, 'YYYY-MM-DD')
;
[/php]
说明:
vd: 形成一百天的日期与已有数据中日期的一个并集
vid: 所有的id号
vdid: 日期集合与id集合的一个笛卡儿集
VALL: 所有id所有日期的余额(无值的记录对应余额为null值)
VMIN: 将所有null值替换为最后一笔的余额
有了以上说明, 相信应该比较容易读懂, 不再分解.
语句在样例数据上测试正确(环境: oracle 8.17 + win2000 pro) . 由于篇幅所限, 不在列出测试结果, 朋友们可以自行测试.
语句未考虑优化, 有兴趣的朋友可以提出更好的解决方法. 如有错误, 请指正. |
|