sql查詢最小缺失值與重用被刪除的鍵

2022-07-27 21:57:14 字數 1580 閱讀 8886

在資料處理時,我們經常會使用一些「自增」的插入方式來處理資料。比如學生學號:b07051001,b07051002....類似的遞增關係的資料。

但是,如果中途因為某些原因將其中的一些記錄刪除掉之後,就會出現斷續的記錄。這時,我們可能期待將這些中間的缺失值再次利用。以下,就談談如何查詢最小缺失值。

首先,我們建乙個測試表:tb_test(主鍵並未設定為自增長):

插入一些資料:

刪除某些記錄,製造「斷層」:

delete from tb_test where id in (1,2,4,5,7);

此時表中資料為不連貫的:

此時能看出最小缺失值應該為:1

我們通過下面這段sql能夠得到結果:

select

case

when not exists(select 1 from tb_test where id=1)

then 1

else (

select min(a.id+1)

from tb_test as a

where not exists

(select 1

from tb_test as b

where b.id=a.id+1))

end as '最小缺失值';

這裡使用了乙個小的技巧,原理是將表中所有記錄的id加1,再與源表中所有記錄的id匹配。這樣只要有源表中有id缺失,id+1在源表中就會有匹配不到的值。

比如源表中id序列為:1、2、3、5、7(a.id與b.id),則源表中的id+1序列為: 2、3、4、6、8(a.id+1);

這樣再代入子查詢中,就可以看到a.id+1=4,和a.id+1=6和a.id+1=8在b.id中不存在匹配值。然後再去最小值:min()這樣結果就為4。

但是以上上圖中的這個序列3,6,8用子查詢得出的結果也應該為4,而正確答案為1,顯然只是用子查詢這樣的方式處理是不完整的。

那為什麼要把1單獨判斷呢?這是由1的位置的特殊性決定的。因為1開始時總是處在序列的最前端的位置(正常情況下)。它的前面已經沒有數字了,也就是說不存在a.id+1=1(因為我們預設序列是從1開始增長的)。因此沒有哪個數字存在與否能判斷出1是否存在。所以1需要單獨考慮。

處於同樣的原理,我們可以用這種方式重用被刪除的鍵:

只要在前面加上:insert into ti_test(id,val) select .....(同上)即可。

當然你可以使用coalesce函式來合併,存在1和不存在1的情況:

如下:select coalesce(min(a.id+1),1)

from tb_test a

where not exists (

select 1

from tb_test as b

where b.id=a.id+1

) and exists(select 1 from tb_test where id=1)

注:coalesce函式用於返回第乙個非空值。也就是說如果序列中沒有1,在被where篩選器篩選後,返回的值為null,此時min(a.id+1)也為null,這樣返回的結果就為1。

最後,並不推薦重用返回值並且在多執行緒執行時也可能得到重複的鍵。

sql查詢最小缺失值與重用被刪除的鍵

在資料處理時,我們經常會使用一些 自增 的插入方式來處理資料。比如學生學號 b07051001,b07051002.類似的遞增關係的資料。但是,如果中途因為某些原因將其中的一些記錄刪除掉之後,就會出現斷續的記錄。這時,我們可能期待將這些中間的缺失值再次利用。以下,就談談如何查詢最小缺失值。首先,我們...

sql查詢最小缺失值與重用被刪除的鍵

在資料處理時,我們經常會使用一些 自增 的插入方式來處理資料。比如學生學號 b07051001,b07051002.類似的遞增關係的資料。但是,如果中途因為某些原因將其中的一些記錄刪除掉之後,就會出現斷續的記錄。這時,我們可能期待將這些中間的缺失值再次利用。以下,就談談如何查詢最小缺失值。首先,我們...

分組查詢最大 最小值sql

經典題目 查詢每個班級的最高分,查詢每種日誌的最晚記錄 1.查詢每個班級的最高分 不考慮同一分數的 思路 首先利用max group by取出每組最高的分數,再與表自連線 sql語句 select t1.id,t1.name,t1.calssid,t2.score from t zhb t1 sel...