2011-10-28 6 views
0

그래서 위험 할 정도로 SQL을 알 수 있습니다. SQLite 데이터베이스의 데이터 섹션을 표시하고 특정 기준에 따라 일부 데이터를 반복 할 수 있어야하는 응용 프로그램을 개발 중입니다. SQLite는 하위 쿼리의 쿼리 별 인덱스를 찾습니다.

create table packets(id INTEGER PRIMARY KEY, timestamp varchar(32), type varchar(32), source varchar(32), destination varchar(32), channel varchar(16), first_sequence integer, last_sequence integer, missing integer); 

가 그럼 난 특정 기준에 따라 데이터의 일부 또는 전부를 표시하는보기가 있습니다

그래서 나는이처럼 보이는 테이블이 있습니다.

우리는 수백만 개의 행이있는 테이블에 대해 말하고 있습니다. 따라서이 모든 것을 메모리에로드 할 수 없습니다. 그래서 뷰의 인덱스를 기반으로 각 항목을 개별적으로 요청하는 뷰 클래스가 있습니다.

그래서 예를 들면, 나는 'C'의 채널 값이 모든 패킷을 표시하고, 그리고보기는 내가 데이터베이스에이 쿼리를 발행 할 첫 번째 항목을 그릴 준비가있는 경우 :

SELECT * FROM packets WHERE channel='C' LIMIT 1 OFFSET 0 
을 이 두 번째 항목을 그릴 준비가되면

나는

이 잘 작동 ...

SELECT * FROM packets WHERE channel='C' LIMIT 1 OFFSET 1 

을한다. 아마 최선의 방법은 아니라는 것을 알았지 만 SQLite를 사용하는 가장 간단한 방법을 배우고 나중에 최적화하는 것에 대해 걱정하려고합니다.

이제는 다른 검색 기준에 따라이 결과 집합 내에서 항목을 찾고 원래 결과 집합 내에서 색인을 가져올 수 있어야합니다.

예를 들어 "누락"값이 1 인 원래 결과 집합 내의 항목을 반복 할 수 있어야하며 해당 항목의보기 색인을 파악할 수 있어야합니다.

나는 내가이 비슷한 그것을 할 수 있다고 생각 테이블에 설정되어있는 전체 데이터를 사용하고있는 경우 :

SELECT rowid FROM packets WHERE rowid > [currentlySelectedRowID] AND missing=1 LIMIT 1 

을하지만을 나는 데이터의 ROWID 아무튼의 부분 집합 내에서 인덱스를 필요로 할 때 정말 도움이 안되며 모든 항목을 개별적으로 반복하지 않고 하위 집합 내에서 색인을 찾는 방법을 모릅니다.

SQL 쿼리로이 작업을 수행하는 방법이나 관련 문서 또는 튜토리얼에 대한 지침은 크게 감사하겠습니다.

감사합니다.

(참고 : 그것은 그것을 설명하는 방법에 내 마음 속에 약간 복잡한, 그래서 뭔가 명확하지 않은 경우 내가 자세히 설명하려고합니다 같은 질문을 이해하지 않을 수 있습니다.)

편집 : 실제로 나는 것을 발견 LIMIT -1 OFFSET [startIndex]을 수행 한 다음 초기 누락 된 항목을 찾을 때까지 단계별 실행을 수행하여 초기 색인 뒤에 전체 결과 집합을 쿼리함으로써 성능 측면에서 충분합니다. 나중에 참조 할 수 있도록 SQL 문으로 처리하는 방법이 있는지 알고 있으면 유용 할 것입니다.

답변

1

둘 이상의 행을 반환하는 SELECT 문에 ORDER BY 절이 없으면 행이 반환되는 순서는 정의되지 않습니다.

초기 쿼리에는 중요하지 않지만 하위 집합의 도메인에 대해 동일한 초기 집합을 사용하려는 경우 행의 하위 집합을 만들어야 할 때 중요하게 나타납니다.

사용

SELECT rowid,* FROM packets WHERE channel='C' ORDER BY rowid LIMIT N? OFFSET M? 

결과에 주문을 부과합니다. 그런 다음 서브 세트를 찾으려면

SELECT rowid 
FROM (SELECT rowid,* FROM packets WHERE channel='C' ORDER BY rowid LIMIT N? OFFSET M?) 
WHERE missing=1 LIMIT 1 

중에서 선택할 수 있습니다.

추가 정보 : 기본 SELECT 문에서 반환 된 "ROWID"가이 임시 테이블의 ROWID를 반영합니까?

... ORDER BY에 대한 팁을위한

sqlite> create table packets (channel, missing); 
sqlite> insert into packets values ('A',0); 
sqlite> insert into packets values ('B',0); 
sqlite> insert into packets values ('C',0); 
sqlite> select * from packets; 
A|0 
B|0 
C|0 
sqlite> create temp table tt as SELECT rowid,* FROM packets WHERE channel='C'; 
sqlite> select rowid,* from tt; 
3|3|C|0 
sqlite> insert into packets values ('C',1); 
sqlite> drop table tt; 
sqlite> create temp table tt as SELECT rowid,* FROM packets WHERE channel='C'; 
sqlite> select rowid,* from tt; 
3|3|C|0 
4|4|C|1 
sqlite> 
+0

덕분에, 난 항상 결과가 ROWID에 의해 주문에 기본값으로 가정한다. 나는 그런 것들을 생각하는 것보다 잘 알아야한다. 내부 어딘가에있는 SELECT 문을 임시 테이블을 만드는 어딘가 읽을 믿습니다. 이 경우, 기본 SELECT 문에서 리턴 된 "rowid"가이 임시 테이블의 rowid를 반영합니까? – Gerald

+0

@Gerald, 예, 답안에 부록을 참조하십시오. –

+0

정보를 제공해 주셔서 감사합니다. 그러나 rowid가 임시 테이블 대신 원본 테이블의 ROWID를 반영하는 것처럼 보입니다. 정말 필요한 것은 패킷의 하위 집합에 대한 인덱스입니다. 즉, 예제를 기반으로 tt에서 첫 번째 '누락'값 1에 대한 쿼리를 수행 한 경우 하위 집합 내의 인덱스를 반영하기 위해 4 대신 인덱스 2를 가져와야합니다. 미안 해요. – Gerald