2015-09-01 5 views
-2

У меня есть таблица, которая варьируется от 1-100000, но есть пробелы в идентификаторах, где элементы были удалены. Я хочу, чтобы оператор SQL возвращал мне список всех неиспользуемых идентификаторов в таблице, чтобы я мог получить список элементов, которые были удалены.SQL Server SQL Получить список неиспользуемых идентификаторов

Я хочу, чтобы список, но рандомизированный список, был бонусом на самом деле. Я думаю, что это может быть сделано с помощью функции ранда ...

Я хотел бы сохранить его в ANSI SQL, если это возможно, чтобы сохранить портативность, но если нет, то это нормально ...

+0

Это звучит скорее как вопрос, чем вопрос; в чем проблема? Что у вас есть на данный момент? – Jeroen

+0

Возможный дубликат [Выбрать значения не в определенном диапазоне в таблице] (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 

Используя таблицу Tally, создайте список чисел от 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

Спасибо человеку. Просто пытаюсь помочь. –

Смежные вопросы