[SQL] 어떻게 일련의 숫자에서 누락 된 번호를 확인하려면?
SQL어떻게 일련의 숫자에서 누락 된 번호를 확인하려면?
나는 대학에 대한 입학 시스템을 만드는 프로젝트를하고있는 중이 야; 기술은 자바와 오라클입니다.
테이블 중 하나에서, 미리 생성 된 일련 번호가 저장된다. 나중에, 그 일련 번호에 대해, 신청자의 형태로 데이터가 입력됩니다. 내 요구 사항은 항목 프로세스가 완료되면 나는 많은 현명한 보고서를 생성 할 것입니다. 수유 중에 일련 번호를 미리 생성 된 경우 어떤 일련 번호가 누락 갔다.
예를 들어, 테이블, 시퀀스 번호는 7001, 7002, 7004, 7005, 7006, 7010를 말할. 위의 시리즈는 7001에서 7010에없는 숫자가 7003, 7007, 7008 및 7009를있는 것이 분명하다
어떤 DBMS가이 번호를 찾을 오라클에서 사용 가능한 기능이나 저장 프로 시저 내 목적을 달성 할 수있는 경우 다음 알고리즘을 제안 해주십시오있다.
나는 자바에 몇 가지 방법을 찾을 수 있지만 속도 나 오라클의 솔루션을 찾고 싶어요.
해결법
-
==============================
1.9 하드 코딩없는 솔루션 :
9 하드 코딩없는 솔루션 :
select min_a - 1 + level from ( select min(a) min_a , max(a) max_a from test1 ) connect by level <= max_a - min_a + 1 minus select a from test1
결과 :
MIN_A-1+LEVEL ------------- 7003 7007 7008 7009 4 rows selected.
-
==============================
2.이 시도:
이 시도:
SELECT t1.SequenceNumber + 1 AS "From", MIN(t2.SequenceNumber) - 1 AS "To" FROM MyTable t1 JOIN MyTable t2 ON t1.SequenceNumber < t2.SequenceNumber GROUP BY t1.SequenceNumber HAVING t1.SequenceNumber + 1 < MIN(t2.SequenceNumber)
여기서, 시퀀스 7001, 7002, 7004, 7005, 7006, 7010에 대한 결과이다 :
From To 7003 7003 7007 7009
-
==============================
3.이 포스트 그레스> = 8.4에서 작동합니다. CTE에 구문에 약간의 수정으로 너무 오라클과 마이크로 소프트 작동하도록 만들어졌다.
이 포스트 그레스> = 8.4에서 작동합니다. CTE에 구문에 약간의 수정으로 너무 오라클과 마이크로 소프트 작동하도록 만들어졌다.
-- EXPLAIN ANALYZE WITH missing AS ( WITH RECURSIVE fullhouse AS ( SELECT MIN(num)+1 as num FROM numbers n0 UNION ALL SELECT 1+ fh0.num AS num FROM fullhouse fh0 WHERE EXISTS ( SELECT * FROM numbers ex WHERE ex.num > fh0.num ) ) SELECT * FROM fullhouse fh1 EXCEPT ( SELECT num FROM numbers nx) ) SELECT * FROM missing;
-
==============================
4.시나리오에 대한 답변을 얻을 수있는 한 가지 간단한 방법이 있습니다 :
시나리오에 대한 답변을 얻을 수있는 한 가지 간단한 방법이 있습니다 :
create table test1 ( a number(9,0)); insert into test1 values (7001); insert into test1 values (7002); insert into test1 values (7004); insert into test1 values (7005); insert into test1 values (7006); insert into test1 values (7010); commit; select n.n from (select ROWNUM + 7001 as n from dual connect by level <= 9) n left join test1 t on n.n = t.a where t.a is null;
선택은 당신에게 당신의 예에서 답을 줄 것이다. 이것은 단지 당신이 미리 알고있는 경우에하는 당신의 숫자는 그 범위해야 너무 크지 범위, 의미가 있습니다. 첫 번째 숫자는 상기 ROWNUM 부 오프셋되어야하며, 시퀀스의 길이 부에 의해 연결의 레벨로 제한된다.
-
==============================
5.나는 스테판 완료했다 당신이 어떤 최대 및 최소 값을 알 필요로하지만, 당신이 당신을 위해 정말 적합하지 않은 것으로,이 성명에서하는 수단을 하위 쿼리를 사용할 수없는 수준으로 연결 제안 것이다 시퀀스입니다.
나는 스테판 완료했다 당신이 어떤 최대 및 최소 값을 알 필요로하지만, 당신이 당신을 위해 정말 적합하지 않은 것으로,이 성명에서하는 수단을 하위 쿼리를 사용할 수없는 수준으로 연결 제안 것이다 시퀀스입니다.
나는 파이프가 늘어선 테이블 기능을 사용하면 가입 할 필요가 숫자를 생성하는 가장 좋은 방법이 될 수 있습니다 제안합니다. 작업이 위해서는 당신에 값을 반환하는 데이터베이스에서 개체를 필요할 것 :
create or replace type t_num_array as table of number;
기능 다음 :
create or replace function generate_serial_nos return t_num_array pipelined is l_first number; l_last number; begin select min(serial_no), max_serial_no) into l_first, l_last from my_table ; for i in l_first .. l_last loop pipe row(i); end loop; return; end generate_serial_nos; /
이 기능을 다음을 사용하여 최소 및 최대 사이에, 일련 번호의 목록을 반환합니다.
select * from table(generate_serial_nos);
어떤 쿼리가되고 일련 번호가 누락 된 찾을 것을 의미 :
select serial_no from ( select * from table(generate_serial_nos) ) generator left outer join my_table actual on generator.column_value = actual.serial_no where actual.serial_no is null
-
==============================
6.이 일을하지만 선택은 이후 첫번째 순서는 (시작 값) 전임자가 없습니다. SQL 서버에서 테스트하지만 오라클에서 작동합니다
이 일을하지만 선택은 이후 첫번째 순서는 (시작 값) 전임자가 없습니다. SQL 서버에서 테스트하지만 오라클에서 작동합니다
SELECT s.sequence FROM seqs s WHERE s.sequence - (SELECT sequence FROM seqs WHERE sequence = s.sequence-1) IS NULL
여기서 테스트 결과는
Table ------------- 7000 7001 7004 7005 7007 7008 Result ---------- 7000 7004 7007
할당 시퀀스를 얻기 위해서는, 단지 값을 [I] - 전 예컨대 큰 제 1 행을 (- 1 = 7003와 7007-7004 (7006) = 1) 서열을 이용할 수있다
난 당신이 간단한 쿼리를 개선 할 수 있다고 생각
-
==============================
7.여기에 솔루션이입니다 :
여기에 솔루션이입니다 :
SQL :
WITH MentionedValues /*this would just be your actual table, only defined here to provide data for this example */ AS (SELECT * FROM ( SELECT LEVEL + 7000 seqnum FROM DUAL CONNECT BY LEVEL <= 10000) WHERE seqnum NOT IN (7003,7007,7008,7009)--omit those four per example ), Ranges /*identifies all ranges between adjacent rows*/ AS (SELECT seqnum AS seqnum_curr, LAG (seqnum, 1) OVER (ORDER BY seqnum) AS seqnum_prev, seqnum - (LAG (seqnum, 1) OVER (ORDER BY seqnum)) AS diff FROM MentionedValues) SELECT Ranges.*, ( SELECT LISTAGG (Ranges.seqnum_prev + LEVEL, ',') WITHIN GROUP (ORDER BY 1) FROM DUAL CONNECT BY LEVEL < Ranges.diff) "MissingValues" /*count from lower seqnum+1 up to lower_seqnum+(diff-1)*/ FROM Ranges WHERE diff != 1 /*ignore when diff=1 because that means the numers are sequential without skipping any*/ ;
산출:
SEQNUM_CURR SEQNUM_PREV DIFF MissingValues 7004 7002 2 "7003" 7010 7006 4 "7007,7008,7009"
-
==============================
8.
SELECT ROWNUM "Missing_Numbers" FROM dual CONNECT BY LEVEL <= (SELECT MAX(a) FROM test1) MINUS SELECT a FROM test1 ;
-
==============================
9.향상된 쿼리는 다음과 같습니다
향상된 쿼리는 다음과 같습니다
SELECT ROWNUM "Missing_Numbers" FROM dual CONNECT BY LEVEL <= (SELECT MAX(a) FROM test1) MINUS SELECT ROWNUM "Missing_Numbers" FROM dual CONNECT BY LEVEL < (SELECT Min(a) FROM test1) MINUS SELECT a FROM test1;
참고 : 우리가 누락 가치를 찾을 수있는 열입니다.
-
==============================
10.
select A.ID + 1 As ID From [Missing] As A Where A.ID + 1 Not IN (Select ID from [Missing]) And A.ID < n Data: ID 1 2 5 7 Result: ID 3 4 6
from https://stackoverflow.com/questions/10968493/how-to-check-any-missing-number-from-a-series-of-numbers by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 일반 LINQ 쿼리의 조건? (0) | 2020.06.24 |
---|---|
[SQL] 안드로이드에 SQLite 데이터베이스에 ArrayList에 저장 (0) | 2020.06.24 |
[SQL] 다른 MySQL의 데이터베이스에 하나의 MySQL 데이터베이스에서 테이블을 복사하는 방법 (0) | 2020.06.24 |
[SQL] 어떻게 SQL Server의 문자열에서 공백 문자를 제거 (0) | 2020.06.24 |
[SQL] SQL 뷰에합니까 JPA 지원 매핑? (0) | 2020.06.24 |