1. 程式人生 > >根據狀態變化情況,求最大值和最小值

根據狀態變化情況,求最大值和最小值

decode date 要求 情況 eight 測試表 技術分享 image group

題目1:根據第一二列,計算出第三列。即:求每組KH_VALUE狀態(1和0)變化的最小時間

技術分享

--創建測試表
create table tmp as
select to_date(2017-04-21 16:22:00,yyyy-mm-dd hh24:mi:ss) dt, 1 kv from dual union all
select to_date(2017-04-21 16:23:00,yyyy-mm-dd hh24:mi:ss) dt, 1 kv from dual union all
select to_date(2017-04-21 16:24:00,yyyy-mm-dd hh24:mi:ss
) dt, 0 kv from dual union all select to_date(2017-04-21 16:25:00,yyyy-mm-dd hh24:mi:ss) dt, 0 kv from dual union all select to_date(2017-04-21 16:26:00,yyyy-mm-dd hh24:mi:ss) dt, 0 kv from dual union all select to_date(2017-04-21 16:27:00,yyyy-mm-dd hh24:mi:ss) dt, 0 kv from dual union all select to_date(
2017-04-21 16:28:00,yyyy-mm-dd hh24:mi:ss) dt, 1 kv from dual union all select to_date(2017-04-21 16:29:00,yyyy-mm-dd hh24:mi:ss) dt, 1 kv from dual union all select to_date(2017-04-21 16:30:00,yyyy-mm-dd hh24:mi:ss) dt, 0 kv from dual union all select to_date(2017-04-21 16:31:00,yyyy-mm-dd hh24:mi:ss) dt, 0
kv from dual; --SQL實現: select dt,kv,min(dt)over(partition by rn order by dt) new_dt from(select dt,kv,sum(kv2)over(order by dt) rn from(select dt,kv, --case when lag(kv,1)over(order by dt) = kv then 0 else 1 end kv2 case when lag(kv,1)over(order by dt) = kv then 0 else row_number()over(order by dt) end kv2 from tmp ) )

題目2:按照c1的順序,求出c2狀態發生變化的開始及結束位置。

已知tmp表數據如下:
c1 c2
------
1 1
2 1
4 1
5 0
6 0
7 0
8 1
9 1
10 1
11 1
12 1
13 0
14 1
15 1
16 1
17 1
18 1
19 1

c1列為編號,c2為狀態(0,1),要求實現下面的效果:

開始位置,結束位置,狀態
1,4,1
5,7,0
8,12,1
13,13,0,
14,19,1

--創建測試表
create table tmp(c1 int ,c2 int );
insert into tmp values(1,1);
insert into tmp values(2,1);
insert into tmp values(4,1);
insert into tmp values(5,0);
insert into tmp values(6,0);
insert into tmp values(7,0);
insert into tmp values(8,1);
insert into tmp values(9,1);
insert into tmp values(10,1);
insert into tmp values(11,1);
insert into tmp values(12,1);
insert into tmp values(13,0);
insert into tmp values(14,1);
insert into tmp values(15,1);
insert into tmp values(16,1);
insert into tmp values(17,1);
insert into tmp values(18,1);
insert into tmp values(19,1);

--解法1:
select min(c1) start_c1,
max(c1) start_c2
c2
from(select c1,c2,
sum(rn)over(order by c1) rn
from(select c1,
c2,
decode(c2, lag(c2) over(order by c1), null, row_number() over(order by c1)) rn
from tmp
)
)
group by rn, c2;

--解法2:
select min(c1), max(c1), c2
from (select b.*,
row_number()over(partition by g order by c1) r1,
row_number()over(partition by g order by c1 desc) r2
from (select a.*, sum(t) over(order by c1) g
from (select t.*, decode(c2, lag(c2, 1, c2) over(order by c1), 0, 1) t
from tmp t
)a
) b
) c
where r1 = 1 or r2 = 1
group by g, c2
order by 1;

--解法3:
select min(c1) s, max(c1) e, c2
from (select c1, c2, sum(rn) over(order by c1) rn
from (select c1, c2,
case when lag(c2) over(order by c1) = c2 then 0 else 1 end rn
from tmp
)
)
group by c2, rn
order by s

根據狀態變化情況,求最大值和最小值