[SQL] SQL 서버에서 가장 작은 사용되지 않는 번호 찾기
SQLSQL 서버에서 가장 작은 사용되지 않는 번호 찾기
당신은 어떻게 SQL 서버 열에서 가장 작은 사용하지 않는 번호를 찾을 수 있습니까?
나는 SQL Server 테이블에 엑셀에서 수동으로 기록 된 많은 수의 레코드를 가져 오는에 대해 생각합니다. 지금부터 내 웹 사이트가 새 레코드를 기록하는 경우에 의미, 그들은 모두 숫자 ID (라는 문서 번호)를 가지고 있지만, 그들은 더 이상이 적용된다는 이유로 순차적으로 할당되지되지 않은, 그것은 (그에게 가능한 가장 작은 문서 번호를 할당 할 필요가 이미 사용되지 않은 0보다 큰).
일반 SQL을 통해이 할 수있는 방법이 있나요 또는이 TSQL / 코드에 대한 문제?
감사!
편집하다
동시성의 문제를 제기하기위한 WW 특별 감사. 이 웹 응용 프로그램임을 감안할 때, 충돌을 방지하기 위해 코드 또는 DB 수준 잠금 중 하나를 고려해야 멀티 스레드 정의와이 같은 문제에 직면 사람입니다.
LINQ
참고 -이 다음 코드를 사용하여 LINQ를 통해 수행 할 수 있습니다 :
var nums = new [] { 1,2,3,4,6,7,9,10};
int nextNewNum = (
from n in nums
where !nums.Select(nu => nu).Contains(n + 1)
orderby n
select n + 1
).First();
nextNewNum == 5
해결법
-
==============================
1.+ 1 ID로 행이 존재하지 않는 첫 번째 행을 찾기
+ 1 ID로 행이 존재하지 않는 첫 번째 행을 찾기
SELECT TOP 1 t1.Id+1 FROM table t1 WHERE NOT EXISTS(SELECT * FROM table t2 WHERE t2.Id = t1.Id + 1) ORDER BY t1.Id
편집하다:
가장 낮은 기존의 ID가 여기에, 1이 아닌 추한 솔루션이다 특별한 경우를 처리하려면 :
SELECT TOP 1 * FROM ( SELECT t1.Id+1 AS Id FROM table t1 WHERE NOT EXISTS(SELECT * FROM table t2 WHERE t2.Id = t1.Id + 1 ) UNION SELECT 1 AS Id WHERE NOT EXISTS (SELECT * FROM table t3 WHERE t3.Id = 1)) ot ORDER BY 1
-
==============================
2.당신이 숫자 ID별로 정렬하는 경우, 당신이 찾고있는 수는 ROW_NUMBER () 함수는 ID와 동일하지 않습니다하는 최초의 하나가 될 것입니다.
당신이 숫자 ID별로 정렬하는 경우, 당신이 찾고있는 수는 ROW_NUMBER () 함수는 ID와 동일하지 않습니다하는 최초의 하나가 될 것입니다.
-
==============================
3.지금까지 답변의에서 잠금이나 동시성에 대한 언급이 없습니다.
지금까지 답변의에서 잠금이나 동시성에 대한 언급이 없습니다.
이 두 사용자가 거의 같은 시간에 문서를 추가하는 것을 고려 : -
User 1 User 2 Find Id Find Id Id = 42 Id = 42 Insert (42..) Insert (42..) Error!
당신이 중 하나를해야합니다 A) 그 오류를 처리하고 다음 사용 가능한 아이디를 찾고 다시 루프를 돌아 다니면서, OR b)는 이렇게 단 1 사용자가 특정 시간에 ID를 찾고있는 과정의 시작에 잠금을 꺼내
-
==============================
4.
SELECT TOP 1 t1.id+1 FROM mytable t1 LEFT OUTER JOIN mytable t2 ON (t1.id + 1 = t2.id) WHERE t2.id IS NULL ORDER BY t1.id;
이 @Jeffrey Hantlin 및 @Darrel 밀러에 의해 주어진 상관 하위 쿼리를 사용하여 답변에 대한 대안입니다.
그러나이 설명하고있는 정책은 정말 좋은 생각이 아니다. ID 값은 고유해야하지만, 연속적 일 필요가되어서는 안된다.
당신은 # 42, 문서에 대한 링크와 함께 사람을 이메일을 보내 다음 나중에 문서를 삭제하면 어떻게됩니까? 나중에 새 문서의 ID 번호 (42)를 다시 사용합니다. 이제 전자 메일의 수신자가 잘못된 문서에 대한 링크를 따를 것이다!
-
==============================
5.
declare @value int select @value = case when @value is null or @value + 1 = idcolumn then idcolumn else @value end from table order by idcolumn select @value + 1
1 표 2 스캔 해시 일치보다는 스캔합니까 그리고 상단의 대답처럼 가입
-
==============================
6.간격이 순서가있는 경우, 당신은 이런 일에 최초의 차이를 찾을 수 있습니다 :
간격이 순서가있는 경우, 당신은 이런 일에 최초의 차이를 찾을 수 있습니다 :
select top 1 (found.id + 1) nextid from (select id from items union select 0) found where not exists (select * from items blocking where blocking.id = found.id + 1) order by nextid asc
즉, 그의 후계자 존재하지 않는 최소한의 ID를 발견하고, 그 후임을 반환합니다. 틈이 없을 경우, 가장 큰 현존하는 ID에 1을 더한를 반환합니다. 0 틀 ID는 1로 시작하는 ID가 고려되는 것을 보장하기 위해 삽입된다.
이 적어도 N 로그 N 시간이 걸릴 수 있습니다.
당신은 절차 적 코드에 의존 할 필요가 없습니다 수 있도록 마이크로 소프트 SQL은 삽입 문에 절에서의 사용을 허용한다.
-
==============================
7.그것은 가능한 가장 작은 수를이어야하는 이유가 있나요? 왜 구멍을 작성해야합니까?
그것은 가능한 가장 작은 수를이어야하는 이유가 있나요? 왜 구멍을 작성해야합니까?
광고에 편집 대답은 비즈니스 규칙은 이후.
DECLARE @counter int DECLARE @max SET @counter = 0 SET @max = SELECT MAX(Id) FROM YourTable WHILE @counter <= @max BEGIN SET @counter = @counter + 1 IF NOT EXISTS (SELECT Id FROM YourTable WHERE Id = @counter) BREAK END END
(이 100 % 정확하지 않을 수 있습니다 그래서는 DB 편리하지 않습니다,하지만 당신은 거기에서 그것을 얻을 수있을 것입니다)
-
==============================
8.
select MIN(NextID) NextUsableID from ( select (case when c1 = c2 then 0 else c1 end) NextID from ( select ROW_NUMBER() over (order by record_id) c1, record_id c2 from myTable) ) where NextID > 0
-
==============================
9.다음은 간단한 방법이다. 그것은 더 빨리하지 않을 수 있습니다. 그것은 처음에 번호가 누락 찾을 수 없습니다.
다음은 간단한 방법이다. 그것은 더 빨리하지 않을 수 있습니다. 그것은 처음에 번호가 누락 찾을 수 없습니다.
SELECT MIN(MT1.MyInt+1) FROM MyTable MT1 LEFT OUTER JOIN MyTable MT2 ON (MT1.MyInt+1)=MT2.MyInt WHERE MT2.MyInt Is Null
-
==============================
10.이제 당신의 ID를 항상 1로 시작해야 가정 해 봅시다 :
이제 당신의 ID를 항상 1로 시작해야 가정 해 봅시다 :
SELECT MIN(a.id) + 1 AS firstfree FROM (SELECT id FROM table UNION SELECT 0) a LEFT JOIN table b ON b.id = a.id + 1 WHERE b.id IS NULL
전혀 기존 레코드를 포함하여 - 이것은 내가 생각할 수있는 모든 경우를 처리합니다.
나는이 솔루션에 대해 좋아하지 않는 유일한 것은 추가 조건 그렇게 두 번 포함해야한다는 것입니다 :
SELECT MIN(a.id) + 1 AS firstfree FROM (SELECT id FROM table WHERE column = 4711 UNION SELECT 0) a LEFT JOIN table b ON b.column = 4711 AND b.id = a.id + 1 WHERE b.id IS NULL
채우기 격차에 대한 요구 사항은 대부분의 경우에 나쁜 디자인과 문제가 발생할 수 있습니다 - 또한 잠금 및 동시성에 대한 의견을주의하시기 바랍니다. 그러나, 나는 그것을 할 수있는 좋은 이유가 있었다 다음 ID를 인쇄하고 인간에 의해 입력 할 수있는 모든 저 사람이없는 동안 우리는 약간의 시간이 지나면 많은 자리 ID를하고 싶지 않아 ...
-
==============================
11.당신은 정말 IDENTITY에 열을 변환하려고합니다. 그들은 문서 수 1로부터 시작 있도록 BACKUP은 먼저 문서 ID를 업데이트 할 ROW_NUMBER를 사용합니다. 숫자 열이 다른 테이블 (외래 키) 참조로 사용하는 경우 때문에 SQL Server는 외래 키를 업데이트하려고 어쩌면 충돌 때문에 실패 시점에서 WHILE 하나에서 수행해야합니다. 결국 단지 열의 정체성 사양을 수 있습니다.
당신은 정말 IDENTITY에 열을 변환하려고합니다. 그들은 문서 수 1로부터 시작 있도록 BACKUP은 먼저 문서 ID를 업데이트 할 ROW_NUMBER를 사용합니다. 숫자 열이 다른 테이블 (외래 키) 참조로 사용하는 경우 때문에 SQL Server는 외래 키를 업데이트하려고 어쩌면 충돌 때문에 실패 시점에서 WHILE 하나에서 수행해야합니다. 결국 단지 열의 정체성 사양을 수 있습니다.
: 그것은 더 많은 작업을 이제하지만 나중에 당신에게 문제를 많이 절약 할 수 있습니다.
-
==============================
12.나는이 대답은 늦게 알고하지만 당신은 재귀 테이블 식을 사용하여 최소 사용되지 않는 번호를 찾을 수 있습니다 :
나는이 대답은 늦게 알고하지만 당신은 재귀 테이블 식을 사용하여 최소 사용되지 않는 번호를 찾을 수 있습니다 :
CREATE TABLE Test ( ID int NOT NULL ) --Insert values here ;WITH CTE AS ( --This is called once to get the minimum and maximum values SELECT nMin = 1, MAX(ID) + 1 as 'nMax' FROM Test UNION ALL --This is called multiple times until the condition is met SELECT nMin + 1, nMax FROM CTE WHERE nMin < nMax ) --Retrieves all the missing values in the table. Removing TOP 1 will --list all the unused numbers up to Max + 1 SELECT TOP 1 nMin FROM CTE WHERE NOT EXISTS ( SELECT ID FROM Test WHERE nMin = ID )
-
==============================
13.나는 비슷한 문제에 직면하고이 함께했다 :
나는 비슷한 문제에 직면하고이 함께했다 :
Select Top 1 IdGapCheck From (Select Id, ROW_NUMBER() Over (Order By Id Asc) AS IdGapCheck From dbo.table) F Where Id > IdGapCheck Order By Id Asc
-
==============================
14.오라클 DB의 경우이 작업을 수행해야합니다
오라클 DB의 경우이 작업을 수행해야합니다
SELECT MIN(NI) FROM (SELECT ROWNUM AS NI,YOUR_ID FROM (SELECT YOUR_ID FROM YOUR_TABLE ORDER BY YOUR_ID ASC)) WHERE NI<>YOUR_ID
-
==============================
15.ROW_NUMBER () 함수의 예 :
ROW_NUMBER () 함수의 예 :
IF NOT 존재 FROM (SELECT TOP 1 ROW_NUM t (표 FROM ROW_NUMBER () OVER (ORDER BY 이드) ROW_NUM 이드 해당) WHERE t.Id> t.row_num) SELECT MAX (ID) 테이블에서 +1 FROM ELSE SELECT TOP 1 ROW_NUM t (표 FROM ROW_NUMBER () OVER (ORDER BY 이드) ROW_NUM 이드 해당) WHERE t.Id> t.row_num;
from https://stackoverflow.com/questions/684106/find-the-smallest-unused-number-in-sql-server by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] LINQ를 검색 와일드 카드 (0) | 2020.04.11 |
---|---|
[SQL] 날짜 범위 사이에 날짜를 얻기 (0) | 2020.04.11 |
[SQL] 어떻게 목록 파일에 SQL 서버의 폴더 내부 (0) | 2020.04.11 |
[SQL] SQL 그룹에 의해 및 최대 (0) | 2020.04.11 |
[SQL] SQL Server에서 lastIndexOf에서도이 있습니까? (0) | 2020.04.10 |