2014-10-08 86 views
0

我有一個表有一個主鍵user_id的用戶,當我們插入一個user_details.Now時它會自動增加我有一個需求,我需要列出所有的缺少(或刪除)user_ids。 我試過這種方式。從一個自動遞增的主鍵列出丟失的ID

DECLARE @NUMBER BIGINT = (SELECT MIN(USER_ID) FROM USERS) 

DECLARE @MAX BIGINT = (SELECT MAX(USER_ID) FROM USERS) 

CREATE TABLE TEMP_USERS (USER_ID BIGINT) 

WHILE @NUMBER <= @MAX 
BEGIN 
    INSERT INTO TEMP_USERS 
     VALUES(@NUMBER); 

    SET @NUMBER = @NUMBER+1; 
END 

SELECT USER_ID from TEMP_USERS 
EXCEPT 
SELECT USER_ID from USERS 

但這需要太長時間。 有沒有其他方法來提高性能?

感謝, 維傑

+0

的要求是很奇怪的序列中越100缺少的用戶ID;如果您需要知道按鍵序列中的缺失值,通常需要將自動增量字段用於不適合的內容。你的執行計劃說什麼?瓶頸在哪裏?信息越少,答案越模糊。作爲一個狂熱的客人,不保證嘗試使用連接而不是「EXCEPT」。 – Paolo 2014-10-08 08:01:58

回答

2

如果您正在使用MSSQL 2005+。然後,你可以這樣做:

DECLARE @NUMBER BIGINT =(SELECT MIN(USER_ID) from USERS) 
DECLARE @MAX BIGINT =(SELECT MAX(USER_ID) from USERS) 

;WITH Nbrs (n) AS (
     SELECT @NUMBER UNION ALL 
     SELECT 1 + n FROM Nbrs WHERE n < @MAX) 
SELECT 
    Nbrs.n AS USERID 
FROM 
    Nbrs 
WHERE NOT EXISTS 
(
    SELECT NULL FROM USERS 
    WHERE USERS.USER_ID=Nbrs.n 
) 
OPTION (MAXRECURSION 0) 

更新

爲了解決意見。 MAXRECURSION在這種情況下做什麼。當我們使用遞歸CTE函數時,可能會以永不結束的方式編寫它。服務器MAXRECURSION是100.這可以通過使用提示,它不應該採取服務器MAXRECURSION覆蓋。

當我們使用0時,它沒有任何MAXRECURSION。如果我們不設置MAXRECURSION,那麼在100行之後,它會崩潰並拋出,並且MAXRECURSION已被滿足。

因爲我們可以預期的是,OP具有我們需要指出,我們要繼續做遞歸直到n < @MAX

+0

可能要添加MAXRECURSION – 2014-10-08 08:05:19

+1

@MarkPM:你說得對。我更新了答案。這樣好嗎? – Arion 2014-10-08 08:07:14

+0

OPTION(MAXRECURSION 0)在此表示什麼?誰能解釋一下? – Mukund 2014-10-08 08:24:31