假设我有这样的数据集(在 Oracle 11g 数据库环境中)
CHANGE_DATE VALUE
------------------ ----------
03-NOV-13 06.56.01 3027.97
03-NOV-13 06.57.01 3030.59
03-NOV-13 06.58.01 3032.33
03-NOV-13 06.59.01 3047.41
03-NOV-13 07.00.02 3045.82
03-NOV-13 07.01.01 3046.63
03-NOV-13 07.02.01 3020.29
03-NOV-13 07.03.02 3019.38
03-NOV-13 07.04.01 3020.76
03-NOV-13 07.05.01 3008.53
我感兴趣的是一个 select 语句,它只显示足够大的变化的值,例如 0.1%。在上述数据集中,所需的输出将是
03-NOV-13 06.56.01 3027.97
03-NOV-13 06.58.01 3032.33
03-NOV-13 06.59.01 3047.41
03-NOV-13 07.04.01 3020.29
03-NOV-13 07.05.01 3008.53
编辑:解释目的:第一行是第一个参考值。任何后续行值都应与此进行比较。如果相对于参考值的变化不超过 x%,请继续。如果该值确实超过了阈值,请选择此行并将此新值保留为用于比较下一行的参考。
我知道我如何才能实现这样的事情,以防我只是沿着这里讨论的行在整数值之间翻转:选择列值已更改的行
我尝试使用以下方法实现一些东西:
with t as (
select to_date('03-NOV-13 06.56.01','dd/mm/yyyy hh24:mi:ss') change_date, 3027.97 value from dual union all
select to_date('03-NOV-13 06.57.01','dd/mm/yyyy hh24:mi:ss'), 3030.59 from dual union all
select to_date('03-NOV-13 06.58.01','dd/mm/yyyy hh24:mi:ss'), 3032.33 from dual union all
select to_date('03-NOV-13 06.59.01','dd/mm/yyyy hh24:mi:ss'), 3047.41 from dual union all
select to_date('03-NOV-13 07.00.02','dd/mm/yyyy hh24:mi:ss'), 3045.82 from dual union all
select to_date('03-NOV-13 07.01.01','dd/mm/yyyy hh24:mi:ss'), 3046.63 from dual union all
select to_date('03-NOV-13 07.02.01','dd/mm/yyyy hh24:mi:ss'), 3020.29 from dual union all
select to_date('03-NOV-13 07.03.02','dd/mm/yyyy hh24:mi:ss'), 3019.38 from dual union all
select to_date('03-NOV-13 07.04.01','dd/mm/yyyy hh24:mi:ss'), 3020.76 from dual union all
select to_date('03-NOV-13 07.05.01','dd/mm/yyyy hh24:mi:ss'), 3008.53 from dual )
, x as ( select value, ROUND(value,-1) round_value, change_date, ROW_NUMBER() OVER (ORDER BY change_date) as rn from t order by change_date) select x.value, x.change_date from x join x y on x.rn = y.rn+1 and x.round_value <> y.round_value;
这使
3047.41 03-NOV-13
3020.29 03-NOV-13
3008.53 03-NOV-13
这不是太离谱,但总是只与前一个值而不是第一个未抑制的值进行比较。显然,这只是进行了四舍五入,并不寻找任何百分比变化。
我也尝试过像这样玩滞后
with t as (
select to_date('03-NOV-13 06.56.01','dd/mm/yyyy hh24:mi:ss') change_date, 3027.97 value from dual union all
select to_date('03-NOV-13 06.57.01','dd/mm/yyyy hh24:mi:ss'), 3030.59 from dual union all
select to_date('03-NOV-13 06.58.01','dd/mm/yyyy hh24:mi:ss'), 3032.33 from dual union all
select to_date('03-NOV-13 06.59.01','dd/mm/yyyy hh24:mi:ss'), 3047.41 from dual union all
select to_date('03-NOV-13 07.00.02','dd/mm/yyyy hh24:mi:ss'), 3045.82 from dual union all
select to_date('03-NOV-13 07.01.01','dd/mm/yyyy hh24:mi:ss'), 3046.63 from dual union all
select to_date('03-NOV-13 07.02.01','dd/mm/yyyy hh24:mi:ss'), 3020.29 from dual union all
select to_date('03-NOV-13 07.03.02','dd/mm/yyyy hh24:mi:ss'), 3019.38 from dual union all
select to_date('03-NOV-13 07.04.01','dd/mm/yyyy hh24:mi:ss'), 3020.76 from dual union all
select to_date('03-NOV-13 07.05.01','dd/mm/yyyy hh24:mi:ss'), 3008.53 from dual )
select value, change_date, case when abs( lag(value,1,0) over(order by change_date) - value ) / value > 0.001 then value else lag(value,1,0) over(order by change_date) end start_of_group from t;
这导致
VALUE CHANGE_DA START_OF_GROUP
---------- --------- --------------
3027.97 03-NOV-13 3027.97
3030.59 03-NOV-13 3027.97
3032.33 03-NOV-13 3030.59
3047.41 03-NOV-13 3047.41
3045.82 03-NOV-13 3047.41
3046.63 03-NOV-13 3045.82
3020.29 03-NOV-13 3020.29
3019.38 03-NOV-13 3020.29
3020.76 03-NOV-13 3019.38
3008.53 03-NOV-13 3008.53
这似乎也是朝着正确方向迈出的一步,但也有同样的问题,即不是对“start_of_group”列而是对“value”列进行比较
我将不胜感激有关如何实现这一目标的任何提示。请让我知道问题是否足够清楚,或者我是否应该添加任何信息。
PS第一次发帖,希望我设法以有意义的方式发布问题