關於連續天數的幾個思路。

上個月做了個需求,要求統計一張表中某ID連續出現5天(時間連續5天,也不讓新建表之類的,就是要求純sql來做)的具體信息。一開始就是一臉懵逼,沒思路然後是百度,找到了第一種解法:
1.採用左連接,把單表每次都作爲一張新表,和自身進行左連接(直接看代碼)

select distinct ID from 表A t1 join 表A t2 on  t1.ID =t2.ID and  t1.date=t2.date+1                                                                          
  join 表A t3 on t2.ID=t3.ID and t2.date=t3.date+1
  join 表A t4 on t3.ID=t4.ID and t3.date=t4.date+1
  join 表A t5 on t4.ID=t5.ID and t4.date=t5.date+1

1.5.當時我測試的時候,我的表中有163條數據,其中連續5天的有3個ID滿足,所以這個做法可以。但是我項目到服務器後,服務器上的數據有6萬多條,滿足條件的有50幾個,然後我的sql跑起來,服務器瞬間連接掛了,(由於連接資源是有限制的)5次左連接不停的佔用資源,也沒有釋放,然後其他的連接就全部掉了,所以數據過多,這個方法不行。

2.採用oracle中自帶的函數解決LAG和LEAD—偷偷去其他地方抄了個簡單的解釋(lag 和lead 可以 獲取結果集中,按一定排序所排列的當前行的上下相鄰若干offset 的某個行的某個列(不用結果集的自關聯);
lag ,lead 分別是向前,向後;
lag 和lead 有三個參數,第一個參數是列名,第二個參數是偏移的offset,第三個參數是 超出記錄窗口時的默認值)
)–說白了就是找相鄰的第幾值。上代碼。

其中id是查找的字段,time是時間字段
> SELECT id,
         LAG(time, 4) OVER(PARTITION BY id ORDER BY time) prev_time,time
          from (SELECT id, TRUNC(time) time FROM 表A t2
                         GROUP BY output_id, TRUNC(time))
         where prev_time IS NOT NULL
           AND (time - prev_time) = 4

在服務器上面跑,沒問題。

3.在網上還看到過一種方法,用遞歸。(大神寫的代碼有點長,看不下去,我貼上原代碼,有興趣的可以看看)(連續打卡,需求差不多)。

with t1(id,rq) as (
  select distinct 人員, date fromwhere date>='2013-11-01' and date<'2013-12-01' ),
--t1求出指定月的人員編號及不同的打卡日期
t2 as (select s2.* from t1 s1 join t1 s2 on s1.id=s2.id and s1.rq=s2.rq-1),
--t2求出所有上一日也打過卡的日期
t3 as (select * from t1 except select * from t2),
--t3求出所有上一日未打過卡的日期
t as ( 
  select id,rq,1 days from t3 
  union all 
  select t1.id,t1.rq,t.days+1 from t1 join t on t1.id=t.id and t1.rq=t.rq+1
)
--t4遞歸調用,每連續一日days+1,就是求每一打卡時間是連續的第幾天
select id
from t
group by id
having max(days)>=5
order by id
以上就不刪了,以下可以改短點吧
with t as (
  select 人員 id, date rq, 1 days from 表 t1 
    where not exists(select * from 表 t2 where t2.date=t1.date-1) 
  union all
  select t1.id,t1.rq,t.days+1 from 表 t1 join t on t1.id=t.id and t1.rq=t.rq+1

)
select id
from t
group by id
having max(days)>=5
order by id

總結,有時候適當的的使用oracle自帶的函數,可以很輕易的解決問題。而且在sql中效率會比較高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章