[SQL] 어떻게 SQL로 카운터를 실행에 "차이"를 찾을 수 있습니까?
SQL어떻게 SQL로 카운터를 실행에 "차이"를 찾을 수 있습니까?
나는 SQL 테이블에 카운터 열에서 최초의 "차이"를 찾아 싶습니다. 값 1,2,4 및 5가있는 경우 예를 들어, 나는 3을 찾아 싶습니다.
나는 물론 순서대로 값을 얻을 수동으로 통과,하지만 난 SQL에서 그것을 할 수있는 방법이있을 것입니다 있는지 알고 싶습니다 수 있습니다.
또한, 다른 DBMS의 작업, 매우 표준 SQL해야한다.
해결법
-
==============================
1.에서 MySQL과 PostgreSQL을 :
에서 MySQL과 PostgreSQL을 :
SELECT id + 1 FROM mytable mo WHERE NOT EXISTS ( SELECT NULL FROM mytable mi WHERE mi.id = mo.id + 1 ) ORDER BY id LIMIT 1
SQL 서버의 경우 :
SELECT TOP 1 id + 1 FROM mytable mo WHERE NOT EXISTS ( SELECT NULL FROM mytable mi WHERE mi.id = mo.id + 1 ) ORDER BY id
오라클의 경우 :
SELECT * FROM ( SELECT id + 1 AS gap FROM mytable mo WHERE NOT EXISTS ( SELECT NULL FROM mytable mi WHERE mi.id = mo.id + 1 ) ORDER BY id ) WHERE rownum = 1
ANSI는 (적어도 효율적인 어디에서나 작동) :
SELECT MIN(id) + 1 FROM mytable mo WHERE NOT EXISTS ( SELECT NULL FROM mytable mi WHERE mi.id = mo.id + 1 )
윈도우 함수 슬라이딩지지 시스템 :
SELECT -- TOP 1 -- Uncomment above for SQL Server 2012+ previd FROM ( SELECT id, LAG(id) OVER (ORDER BY id) previd FROM mytable ) q WHERE previd <> id - 1 ORDER BY id -- LIMIT 1 -- Uncomment above for PostgreSQL
-
==============================
2.귀하의 답변 당신이 첫 번째 값 아이디 = 1이있는 경우 모든 작업의 벌금, 그렇지 않으면이 차이는 감지되지 않습니다. 테이블 ID 값이 3,4,5을 경우 예를 들어, 쿼리는 6을 반환합니다.
귀하의 답변 당신이 첫 번째 값 아이디 = 1이있는 경우 모든 작업의 벌금, 그렇지 않으면이 차이는 감지되지 않습니다. 테이블 ID 값이 3,4,5을 경우 예를 들어, 쿼리는 6을 반환합니다.
나는이 같은 짓을
SELECT MIN(ID+1) FROM ( SELECT 0 AS ID UNION ALL SELECT MIN(ID + 1) FROM TableX) AS T1 WHERE ID+1 NOT IN (SELECT ID FROM TableX)
-
==============================
3.이이 작업을 수행하는 매우 표준 SQL 방법은 정말 아니지만, 절을 제한하는 어떤 형태의 당신이 할 수있는
이이 작업을 수행하는 매우 표준 SQL 방법은 정말 아니지만, 절을 제한하는 어떤 형태의 당신이 할 수있는
SELECT `table`.`num` + 1 FROM `table` LEFT JOIN `table` AS `alt` ON `alt`.`num` = `table`.`num` + 1 WHERE `alt`.`num` IS NULL LIMIT 1
(MySQL은, PostgreSQL을)
또는
SELECT TOP 1 `num` + 1 FROM `table` LEFT JOIN `table` AS `alt` ON `alt`.`num` = `table`.`num` + 1 WHERE `alt`.`num` IS NULL
(SQL 서버)
또는
SELECT `num` + 1 FROM `table` LEFT JOIN `table` AS `alt` ON `alt`.`num` = `table`.`num` + 1 WHERE `alt`.`num` IS NULL AND ROWNUM = 1
(신탁)
-
==============================
4.내 머리에 와서 가장 먼저하는 일. 확실하지가 전혀이 길을 갈 수있는 좋은 아이디어지만 작동해야합니다. 테이블 t이고 컬럼 C 가정하자 :
내 머리에 와서 가장 먼저하는 일. 확실하지가 전혀이 길을 갈 수있는 좋은 아이디어지만 작동해야합니다. 테이블 t이고 컬럼 C 가정하자 :
편집 :이 하나가 빠르게 틱 될 수있다 (짧은!)
-
==============================
5.다른 시스템에서 테스트 할 수 있지만 표준 보인다 ... -이 SQL 서버에서 작동
다른 시스템에서 테스트 할 수 있지만 표준 보인다 ... -이 SQL 서버에서 작동
SELECT MIN(t1.ID)+1 FROM mytable t1 WHERE NOT EXISTS (SELECT ID FROM mytable WHERE ID = (t1.ID + 1))
또한 where 절에 시작 지점을 추가 할 수 있습니다 ...
SELECT MIN(t1.ID)+1 FROM mytable t1 WHERE NOT EXISTS (SELECT ID FROM mytable WHERE ID = (t1.ID + 1)) AND ID > 2000
2003 년과 2004이 존재하지 않는 곳 2000, 2001, 2002 및 2005이 있다면 그래서, 그것은 2003을 반환합니다.
-
==============================
6.다음 솔루션 :
다음 솔루션 :
순차적으로 다음 절 "와"및 예약 번호 순서화 행은 내부 간극 이상으로 ID를 찾고, 행 번호에 참여하지만, 그렇게 한 후에 행과 이전 행을 비교할으로 1만큼 오프셋 회 결과를 재사용 1. 이상에 대한하지만, 더 광범위하게 적용 물었다.
create table #ID ( id integer ); insert into #ID values (1),(2), (4),(5),(6),(7),(8), (12),(13),(14),(15); with Source as ( select row_number()over ( order by A.id ) as seq ,A.id as id from #ID as A WITH(NOLOCK) ) Select top 1 gap_start from ( Select (J.id+1) as gap_start ,(K.id-1) as gap_end from Source as J inner join Source as K on (J.seq+1) = K.seq where (J.id - (K.id-1)) <> 0 ) as G
내부 쿼리를 생성합니다
gap_start gap_end 3 3 9 11
외부 쿼리를 생성합니다
gap_start 3
-
==============================
7.내부는 모든 가능한 값이 뷰 또는 순서에 가입 할 수 있습니다.
내부는 모든 가능한 값이 뷰 또는 순서에 가입 할 수 있습니다.
어떤 테이블하지? 테이블을 확인합니다. 난 항상 그냥이 주변에 더미 테이블을 유지한다.
create table artificial_range( id int not null primary key auto_increment, name varchar( 20 ) null ) ; -- or whatever your database requires for an auto increment column insert into artificial_range( name ) values ( null ) -- create one row. insert into artificial_range( name ) select name from artificial_range; -- you now have two rows insert into artificial_range( name ) select name from artificial_range; -- you now have four rows insert into artificial_range( name ) select name from artificial_range; -- you now have eight rows --etc. insert into artificial_range( name ) select name from artificial_range; -- you now have 1024 rows, with ids 1-1024
그때,
select a.id from artificial_range a where not exists ( select * from your_table b where b.counter = a.id) ;
-
==============================
8.PostgreSQL을 위해
PostgreSQL을 위해
재귀 쿼리를 사용합니다 예.
특정 범위에서 틈을 발견 할 경우에 유용 할 수 있습니다 (표가 빈 상태 (empty)의 경우는 반면 다른 예는하지 않습니다, 심지어 작동합니다)
WITH RECURSIVE a(id) AS (VALUES (1) UNION ALL SELECT id + 1 FROM a WHERE id < 100), -- range 1..100 b AS (SELECT id FROM my_table) -- your table ID list SELECT a.id -- find numbers from the range that do not exist in main table FROM a LEFT JOIN b ON b.id = a.id WHERE b.id IS NULL -- LIMIT 1 -- uncomment if only the first value is needed
-
==============================
9.내 추측:
내 추측:
SELECT MIN(p1.field) + 1 as gap FROM table1 AS p1 INNER JOIN table1 as p3 ON (p1.field = p3.field + 2) LEFT OUTER JOIN table1 AS p2 ON (p1.field = p2.field + 1) WHERE p2.field is null;
-
==============================
10.모든 것을 지금까지 언급이 하나를 차지한다. 그것은 더 값뿐만 아니라 존재하지 않는 경우로 설정됩니다 시작 지점으로 공을 포함한다. 또한 다치 키의 다른 부분에 대한 적절한 위치를 첨가. 이것은 단지 SQL 서버에서 테스트되었습니다.
모든 것을 지금까지 언급이 하나를 차지한다. 그것은 더 값뿐만 아니라 존재하지 않는 경우로 설정됩니다 시작 지점으로 공을 포함한다. 또한 다치 키의 다른 부분에 대한 적절한 위치를 첨가. 이것은 단지 SQL 서버에서 테스트되었습니다.
select MIN(ID) from ( select 0 ID union all select [YourIdColumn]+1 from [YourTable] where --Filter the rest of your key-- ) foo left join [YourTable] on [YourIdColumn]=ID and --Filter the rest of your key-- where [YourIdColumn] is null
-
==============================
11.나는 그것을하는 빠른 방법을 썼다. 확실하지이 가장 효율적이지만 일을 가져옵니다. 그것은 당신에게 차이를 이야기하지만, 이전과의 격차 후 당신에게 ID를 알려줍니다하지 않는 주 (간격이 여러 값이 될 수 명심 그래서 예를 1,2,4,7,11 등을위한)
나는 그것을하는 빠른 방법을 썼다. 확실하지이 가장 효율적이지만 일을 가져옵니다. 그것은 당신에게 차이를 이야기하지만, 이전과의 격차 후 당신에게 ID를 알려줍니다하지 않는 주 (간격이 여러 값이 될 수 명심 그래서 예를 1,2,4,7,11 등을위한)
나는 예로서 SQLite는 사용하고 있습니다
이 테이블 구조 인 경우
create table sequential(id int not null, name varchar(10) null);
이들은 당신의 행은
id|name 1|one 2|two 4|four 5|five 9|nine
쿼리는
select a.* from sequential a left join sequential b on a.id = b.id + 1 where b.id is null and a.id <> (select min(id) from sequential) union select a.* from sequential a left join sequential b on a.id = b.id - 1 where b.id is null and a.id <> (select max(id) from sequential);
https://gist.github.com/wkimeria/7787ffe84d1c54216f1b320996b17b7e
-
==============================
12.
select min([ColumnName]) from [TableName] where [ColumnName]-1 not in (select [ColumnName] from [TableName]) and [ColumnName] <> (select min([ColumnName]) from [TableName])
-
==============================
13.여기에 기준 A의 SQL 솔루션입니다 변화없이 모든 데이터베이스 서버에서 실행 :
여기에 기준 A의 SQL 솔루션입니다 변화없이 모든 데이터베이스 서버에서 실행 :
select min(counter + 1) FIRST_GAP from my_table a where not exists (select 'x' from my_table b where b.counter = a.counter + 1) and a.counter <> (select max(c.counter) from my_table c);
에 대한 행동에 참조;
-
==============================
14.그것은 빈 테이블 또는 네거티브 값으로도 작동합니다. 그냥 SQL 서버 2012에서 테스트
그것은 빈 테이블 또는 네거티브 값으로도 작동합니다. 그냥 SQL 서버 2012에서 테스트
select min(n) from ( select case when lead(i,1,0) over(order by i)>i+1 then i+1 else null end n from MyTable) w
-
==============================
15.당신은 파이어 버드 3를 사용하는 경우이 가장 우아하고 간단하다 :
당신은 파이어 버드 3를 사용하는 경우이 가장 우아하고 간단하다 :
select RowID from ( select `ID_Column`, Row_Number() over(order by `ID_Column`) as RowID from `Your_Table` order by `ID_Column`) where `ID_Column` <> RowID rows 1
-
==============================
16.
-- PUT THE TABLE NAME AND COLUMN NAME BELOW -- IN MY EXAMPLE, THE TABLE NAME IS = SHOW_GAPS AND COLUMN NAME IS = ID -- PUT THESE TWO VALUES AND EXECUTE THE QUERY DECLARE @TABLE_NAME VARCHAR(100) = 'SHOW_GAPS' DECLARE @COLUMN_NAME VARCHAR(100) = 'ID' DECLARE @SQL VARCHAR(MAX) SET @SQL = 'SELECT TOP 1 '+@COLUMN_NAME+' + 1 FROM '+@TABLE_NAME+' mo WHERE NOT EXISTS ( SELECT NULL FROM '+@TABLE_NAME+' mi WHERE mi.'+@COLUMN_NAME+' = mo.'+@COLUMN_NAME+' + 1 ) ORDER BY '+@COLUMN_NAME -- SELECT @SQL DECLARE @MISSING_ID TABLE (ID INT) INSERT INTO @MISSING_ID EXEC (@SQL) --select * from @MISSING_ID declare @var_for_cursor int DECLARE @LOW INT DECLARE @HIGH INT DECLARE @FINAL_RANGE TABLE (LOWER_MISSING_RANGE INT, HIGHER_MISSING_RANGE INT) DECLARE IdentityGapCursor CURSOR FOR select * from @MISSING_ID ORDER BY 1; open IdentityGapCursor fetch next from IdentityGapCursor into @var_for_cursor WHILE @@FETCH_STATUS = 0 BEGIN SET @SQL = ' DECLARE @LOW INT SELECT @LOW = MAX('+@COLUMN_NAME+') + 1 FROM '+@TABLE_NAME +' WHERE '+@COLUMN_NAME+' < ' + cast( @var_for_cursor as VARCHAR(MAX)) SET @SQL = @sql + ' DECLARE @HIGH INT SELECT @HIGH = MIN('+@COLUMN_NAME+') - 1 FROM '+@TABLE_NAME +' WHERE '+@COLUMN_NAME+' > ' + cast( @var_for_cursor as VARCHAR(MAX)) SET @SQL = @sql + 'SELECT @LOW,@HIGH' INSERT INTO @FINAL_RANGE EXEC( @SQL) fetch next from IdentityGapCursor into @var_for_cursor END CLOSE IdentityGapCursor; DEALLOCATE IdentityGapCursor; SELECT ROW_NUMBER() OVER(ORDER BY LOWER_MISSING_RANGE) AS 'Gap Number',* FROM @FINAL_RANGE
-
==============================
17.찾을 방법의 대부분은 MySQL은 매우, 매우 느리게 실행합니다. 다음은 MySQL의 <8.0에 대한 내 솔루션입니다. 끝까지 초 말 ~ 근처의 격차 1M 기록에서 테스트. 확실하지가 다른 SQL 맛을 맞는 경우.
찾을 방법의 대부분은 MySQL은 매우, 매우 느리게 실행합니다. 다음은 MySQL의 <8.0에 대한 내 솔루션입니다. 끝까지 초 말 ~ 근처의 격차 1M 기록에서 테스트. 확실하지가 다른 SQL 맛을 맞는 경우.
SELECT cardNumber - 1 FROM (SELECT @row_number := 0) as t, ( SELECT (@row_number:=@row_number+1), cardNumber, cardNumber-@row_number AS diff FROM cards ORDER BY cardNumber ) as x WHERE diff >= 1 LIMIT 0,1
-
==============================
18.당신의 카운터가 1 일부터 시작되며이 때 빈 시퀀스의 첫 번째 숫자 (1)를 생성하려면, 여기에 오라클 유효 첫 번째 대답에서 코드의 수정 된 부분은 다음과 같습니다
당신의 카운터가 1 일부터 시작되며이 때 빈 시퀀스의 첫 번째 숫자 (1)를 생성하려면, 여기에 오라클 유효 첫 번째 대답에서 코드의 수정 된 부분은 다음과 같습니다
SELECT NVL(MIN(id + 1),1) AS gap FROM mytable mo WHERE 1=1 AND NOT EXISTS ( SELECT NULL FROM mytable mi WHERE mi.id = mo.id + 1 ) AND EXISTS ( SELECT NULL FROM mytable mi WHERE mi.id = 1 )
-
==============================
19.
DECLARE @Table AS TABLE( [Value] int ) INSERT INTO @Table ([Value]) VALUES (1),(2),(4),(5),(6),(10),(20),(21),(22),(50),(51),(52),(53),(54),(55) --Gaps --Start End Size --3 3 1 --7 9 3 --11 19 9 --23 49 27 SELECT [startTable].[Value]+1 [Start] ,[EndTable].[Value]-1 [End] ,([EndTable].[Value]-1) - ([startTable].[Value]) Size FROM ( SELECT [Value] ,ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY [Value]) Record FROM @Table )AS startTable JOIN ( SELECT [Value] ,ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY [Value]) Record FROM @Table )AS EndTable ON [EndTable].Record = [startTable].Record+1 WHERE [startTable].[Value]+1 <>[EndTable].[Value]
-
==============================
20.열의 번호 (1부터 시작) 양의 정수가있는 경우 여기에 쉽게 해결하는 방법입니다. (ID를 가정하면 열 이름입니다)
열의 번호 (1부터 시작) 양의 정수가있는 경우 여기에 쉽게 해결하는 방법입니다. (ID를 가정하면 열 이름입니다)
SELECT TEMP.ID FROM (SELECT ROW_NUMBER() OVER () AS NUM FROM 'TABLE-NAME') AS TEMP WHERE ID NOT IN (SELECT ID FROM 'TABLE-NAME') ORDER BY 1 ASC LIMIT 1
from https://stackoverflow.com/questions/1312101/how-do-i-find-a-gap-in-running-counter-with-sql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL Server 2005는 어떻게 고유 제한 조건을 만들기? (0) | 2020.03.26 |
---|---|
[SQL] 이노 검색 전체 텍스트 (0) | 2020.03.26 |
[SQL] 어떻게 SQL Server 데이터의 스크립트를 얻으려면? [복제] (0) | 2020.03.26 |
[SQL] 변환 대 T-SQL 캐스트 (0) | 2020.03.26 |
[SQL] 정렬 MySQL의 오류의 불법 혼합 (0) | 2020.03.26 |