一個SQL查詢連續三天的流量100以上的資料值【SQql Server】
題目
有一個商場,每日人流量資訊被記錄在這三列資訊中:序號(id)、日期(date)、人流量(people)。請編寫一個查詢語句,找出高峰期時段,要求連續三天及以上,並且每天人流量均不少於100。
例如,表 stadium:
對於上面的示例資料,輸出為:
這個題的題意已經很明白了,就是要找出 連續三天(含)以上人流量都在100(含)以上的資料。
我用SQL Server 來做吧(因為別人都用MySql,正所謂:常在河邊走,哪能都穿鞋?)
我做了點測試資料:
這種題目的思路,就是找到那些資料是即 在100(含)以上,而且又是連續三天對吧?拆分一下思路:
1、每天人流量 >=100
2、連續的天數 要 >=3
你看 我又說了個廢話對吧? >=100簡單,但是 >=3 這個怎麼來呢?也就是怎麼求出連續天數呢?
舉個例子來總結個規律:
1000 - 1 =999 1001 - 2 =999 1002 - 3 =999
發現了嗎,如果一組“減數”和一組“被減數”都是遞增的,那麼他們的差是相同的哦!有沒有猜到我要幹嘛了?
先看一下滿足第1步需的SQL
select * from stadium where people>=100
Q:這樣之後呢?和剛才的規律有毛關係嗎?
A:嗯 目前是沒有的,但是 如果我給他們增加一列“遞增的行號” rownum,和 一例“日期偏移量" dayOffset呢?只要日期連貫,這個dayOffset是否就也是連貫了呢(也就自增了哇)。看圖吧
select *, row_number() over(order by [date]) as rownum ,datediff(day,'1990-1-1',[date]) dayOffset from stadium where people>=100
來觀察一下,兩個紅色框的資料 是不是都是符合要求的?怎麼取出來呢?
還記得前邊總結的【如果一組“減數”和一組“被減數”都是遞增的,那麼他們的差是相同】的例子嗎?這會要用上了
看程式碼:
select *,t1.dayOffset-t1.rownum flag from( select *, row_number() over(order by [date]) as rownum ,datediff(day,'1990-1-1',[date]) dayOffset from stadium where people>=100 )t1
看到沒有?“日期偏移量" -“遞增的行號” 得到的值,如果是連續日期,得到的值相同,如果日期中斷,就會得到一個新的值了,這個就不解釋了吧
得到了這個值之後,我們是不是可以使用partition來做個分割槽求數量 最後過濾呢?來吧 就這樣了
select *,count(*) over(partition by t2.flag) conDays from ( select *,t1.dayOffset-t1.rownum flag from ( select *, row_number() over(order by [date]) as rownum ,datediff(day,'1990-1-1',[date]) dayOffset from stadium where people>=100 )t1 )t2
透徹了不?最後過濾一下 是不是就可以了?順便只顯示目標資料列就可以了:
select t3.ID,t3.[date],t3.people from ( select *,count(*) over(partition by t2.flag) conDays from ( select *,t1.dayOffset-t1.rownum flag from ( select *, row_number() over(order by [date]) as rownum ,datediff(day,'1990-1-1',[date]) dayOffset from stadium where people>=100 )t1 )t2 ) t3 where t3.conDays>=3
這種型別的題目還可以繼續延伸:
比如:高峰期延續最久的時間段範圍?
比如:高峰期持續最長的天數?
類似這種,都可以根據 日期偏移量和行號差的思路來做