[SQL] 從連續號碼中找出缺少的號碼

先來說說結論好了

select

Min(no) as START_VALUE,

Max(no) as END_VALUE

from

(select no,@NUM := @NUM + 1, no-@NUM as diff from A, (select @NUM := 0) AS T1) AS T2

group by diff order by END_VALUE limit 0,1 

再將得出的 END_VALUE +1

就可以找到缺少的號碼了

--

其實以前就有想過這個問題,不過偷懶用了最簡單的方式之後,也至少維持了5年才出現嚴重的問題, 會員編號因為使用六位數字,每新增一個會員,就找出現在在系統裡的最大值,然後加1,但因為部分原因,新增了一個相當後面的數字,造成新加入的會員,都從新的數字開始。中間跨過了非常多的數字無法使用。

這個時後就在思考,我要如何找到中間缺少的數字。

最初,想利用left join自己和自己比對,假設有一個表格A, 欄位是「no」資料有「1,2,3,5,6,7,8,9,12,13,14」

select * from A as t left join A t2 on t1.no <  t2.no and t2.no is null

這樣比對,可以找到該欄位的最大值資料。也就是說如果有一份資料有每個人每一年的資訊,另一個表格B,有三個欄位name、year、num,就可以利用這種方式

select * from B t left join B t2 on t1.year<t2.year and t2.year is null

找到該人員的新一年的資訊

回到正題,原本想利用這種方式,找到數組中間可能相差2以上的最小值,以那個值+1來新增為新的會員編號,卻發現,因為條件是小於的關係,會找到所有每一筆資料小於自己的,但又無法明確的知道要的是哪一個,且資料愈多,執行時間會極度可怕。

最終找到了一個最好解法

將所有數字,找出連續區間,再找到最小的區間組合的最大值+1,就可以找到數組中缺少的最小數字。

以剛剛的表格A為例子

select

Min(no) as START_VALUE,

Max(no) as END_VALUE

from

(select no,@NUM := @NUM + 1, no-@NUM as diff from A, (select @NUM := 0) AS T1) AS T2

group by diff

找到這段sql的時後,其實也稍微理解了一下子

diff = no - @NUM

@NUM是每筆資料的序號,從0開始,每一筆都加一,第一筆資料是1,以此類推,這樣會發現no減掉@NUM,同一數組的diff的是相同,再以diff執行group,就可以取得連續區間的最小值和最大值,再找到最小連續區間的最大值,就可以知道缺少的號碼是多少了。


不再限制您的多媒體創作:使用NDI快速傳輸、處理和編輯高品質的視訊和音訊。

NDI(Network Device Interface)是一種基於IP網絡的視訊和音訊傳輸協議,它可以讓您在同一網絡上的不同設備之間傳輸高品質的視訊和音訊。使用NDI,您可以將視訊和音訊直接傳輸到其他設備上,而不需要使用任何額外的硬體。 以下是使用NDI的步驟: 下載並安裝ND...