2014-10-08 48 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