2015-09-01 22 views
-2

我有一個表格,範圍從1-100000,但在刪除項目的ID中存在空白。我想要一個SQL語句,它會返回表中所有未使用的id的列表,以便我可以獲取已刪除項目的列表。SQL Server SQL獲取未使用的ID列表

我想要列表,但隨機化列表實際上是一種獎勵。我認爲它可以用rand函數來完成...

我想保持它的ANSI SQL如果可能的話,以保持便攜性,但如果沒有,那麼也沒關係......

+0

這聽起來更像是一個問題;什麼是實際問題?你目前有什麼? – Jeroen

+0

[Select a not values in a certain range in a table](http://stackoverflow.com/questions/7648099/select-values-not-in-a-certain-range-in-a-table) – misterMan

+1

我認爲這是你正在尋找的。 http://sqlmag.com/sql-server-2012/solving-gaps-and-islands-enhanced-window-functions – CPMunich

回答

1

你可以做到這一點Tally表的使用。

創建我們的示例數據。

CREATE TABLE #ids(
    id INT IDENTITY(1, 1) 
) 
SET IDENTITY_INSERT #ids ON 
--Insert 100,000 rows 
INSERT INTO #ids(id) 
SELECT TOP 100000 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) 
FROM sys.columns a 
CROSS JOIN sys.columns b 

SET IDENTITY_INSERT #ids OFF; 
-- Randomly delete 1000 rows 
WITH cte AS(
    SELECT TOP 1000 id 
    FROM #ids 
    ORDER BY NEWID() 
) 
DELETE FROM cte 

使用理貨表,創建一個從1 - 100,000的數字列表。然後使用NOT EXISTS獲取未使用的id s。要隨機化列表,請添加ORDER BY NEWID()子句。

DECLARE @min INT = 1, 
     @max INT = 100000 

;WITH E1(N) AS(
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
), 
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), 
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), 
E8(N) AS(SELECT 1 FROM E4 a CROSS JOIN E4 b), 
Tally(N) AS(
    SELECT TOP(@max) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM E8 
) 
SELECT N 
FROM Tally t 
WHERE NOT EXISTS(
    SELECT 1 FROM #ids WHERE id = t.N 
) 
ORDER BY NEWID() -- Sorts the result in a random order 
+1

你應該得到這個完整的示例 – Eric

+0

感謝的人。只是想幫助。 –