DB2의 LIMIT에 해당


91

LIMITiSeries 용 DB2에서 어떻게합니까 ?

50,000 개가 넘는 레코드가있는 테이블이 있는데 0에서 10,000까지 레코드를 반환하고 10,000에서 20,000까지 레코드를 반환하려고합니다.

나는 SQL LIMIT 0,10000에서 쿼리 끝에 0에서 10,000 LIMIT 10000,10000까지 작성하고 쿼리 끝에 10000에서 20,000 까지 작성 한다는 것을 알고 있습니다.

그렇다면 이것은 DB2에서 어떻게 수행됩니까? 코드와 구문은 무엇입니까? (전체 쿼리 예를 들어 주셔서 감사합니다)


ROW_NUMBER ()는 iSeries DB2 V5R4에서만 구현되었습니다. 이전 버전의 경우 유사한 RRN ()을 사용해보십시오.
Paul Morgan

RRN ()은 row_number ()와 완전히 다릅니다.
Brandon Peterson

나를 위해 작동하지 않았습니다. Sytanx 오류입니다.
elcool 2010 년

1
행의 실제 상대 레코드 번호를 제공하는 RRN (파일 이름)을 시도하십시오. RRN은 순차적이지 않으며 행이 삭제 된 경우 번호를 건너 뛸 수 있습니다. RRN은 또한 키별로 순차적이지 않지만 삭제가 발생하지 않은 경우 추가를 기준으로 순차적입니다. 어떤 경우에도 RRN은 행에 대해 고유하며 테이블의 서브 세트를 선택하는 데 사용할 수 있습니다.
Paul Morgan

답변:


139

사용 FETCH FIRST [n] ROWS ONLY:

http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.perf/db2z_fetchfirstnrows.htm

SELECT LASTNAME, FIRSTNAME, EMPNO, SALARY
  FROM EMP
  ORDER BY SALARY DESC
  FETCH FIRST 20 ROWS ONLY;

범위를 얻으려면 ROW_NUMBER()(v5r4부터) 사용하고 다음 WHERE절 내에서 사용해야합니다 . (여기에서 도난 당함 : http://www.justskins.com/forums/db2-select-how-to-123209.html )

SELECT code, name, address
FROM ( 
  SELECT row_number() OVER ( ORDER BY code ) AS rid, code, name, address
  FROM contacts
  WHERE name LIKE '%Bob%' 
  ) AS t
WHERE t.rid BETWEEN 20 AND 25;

그래, 나도 찾았 어, 헤헤. 나는 중간 행도 원한다는 것을 나타 내기 위해 동시에 질문을 편집하고있었습니다.
elcool 2010 년

2
ROW_NUMBER로 다음과 같이해야합니다 : justskins.com/forums/db2-select-how-to-123209.html
Joe

ROW_NUMBER유효한 키워드가 아닙니다. 그러나 링크에 대한 thx, 그것은 나에게 아이디어를줬고 작동합니다.
elcool 2010 년

13

이 방법을 개발했습니다.

주문할 수있는 고유 한 값이있는 테이블이 필요합니다.

10,000 ~ 25,000 행을 원하고 테이블에 40,000 행이있는 경우 먼저 시작점과 총 행을 가져와야합니다.

int start = 40000 - 10000;

int total = 25000 - 10000;

그런 다음 코드로 쿼리에 전달합니다.

SELECT * FROM 
(SELECT * FROM schema.mytable 
ORDER BY userId DESC fetch first {start} rows only ) AS mini 
ORDER BY mini.userId ASC fetch first {total} rows only

10000 번째 행은 결과 집합에서 제외되고 첫 번째 행은 10001 번째 행입니다.
푸른 빛을 띤

1
흥미로운 솔루션입니다. H2 테스트 데이터베이스와의 호환성을 위해 사용하려고했지만 슬프게도 SELECT row_number () OVER (ORDER BY code) 접근 방식보다 ~ 30 배 느리게 작동합니다.
manuna 2013-09-05

9

OFFSET 및 LIMIT에 대한 지원이 최근 i 용 DB2 7.1 및 7.2에 추가되었습니다. 이 지원을 받으려면 다음 DB PTF 그룹 레벨이 필요합니다.

  • IBM i 7.2 용 SF99702 레벨 9
  • IBM i 7.1 용 SF99701 레벨 38

자세한 정보는 여기를 참조하십시오. OFFSET 및 LIMIT 문서 , i 용 DB2 Enhancement Wiki


7

내가 생각해 낸 해결책은 다음과 같습니다.

select FIELD from TABLE where FIELD > LASTVAL order by FIELD fetch first N rows only;

LASTVAL을 0 (또는 텍스트 필드의 경우 '')으로 초기화 한 다음 가장 최근 레코드 집합의 마지막 값으로 설정하면 N 개 레코드 청크로 테이블을 단계별로 진행합니다.


(나는 처음에 당신이 될 테이블의 값을 설정하는 줄 알았는데 화려 당신이 어떤 종류의 필요 했어하지만, 네, 당신이 테이블을 통해 순차적 읽기를하고있는 경우에 작동한다 동시 시스템에 문제를) 열에있는 N동일한 값의 수보다 작은 경우 타이 브레이커 열입니다 (사용하는 경우 에도 ROW_NUMBER()마찬가지 임). 초기 값도 신중하게 선택해야합니다 0. 열에 음수 값이 있으면 분명히 문제가됩니다 . 널에 대한주의가 필요합니다. 페이지를 건너 뛰면 작동하지 않습니다.
Clockwork-Muse 2014

댓글 주셔서 감사합니다. 쿼리를 제어하는 ​​데 사용하는 필드가 고유하고 단조롭게 증가한다는 암시 적 가정이 있다고 생각합니다. 이러한 가정이 유지되지 않으면 테이블의 모든 레코드를 방문 할 수 없다는 데 동의합니다. 그리고 당연히 말이되는 LASTVAL로 시작해야한다는 것이 맞습니다. 일반적으로 "select MINIMUM (FIELD) from TABLE"에 의해 반환되는 모든 항목으로 시작하는 것이 좋습니다. 필드가 인덱싱 된 경우 대부분의 DB 엔진은 전체 테이블을 순차적으로 읽는 것보다 낫습니다.
Tom Barron 2014

2

@elcool의 솔루션 은 현명한 아이디어이지만 총 행 수를 알아야합니다 (쿼리를 실행하는 동안 변경 될 수도 있습니다!). 그래서 수정 된 버전을 제안합니다. 불행히도 2 대신 3 개의 하위 쿼리가 필요합니다.

select * from (
    select * from (
        select * from MYLIB.MYTABLE
        order by MYID asc 
        fetch first {last} rows only 
        ) I 
    order by MYID desc
    fetch first {length} rows only
    ) II
order by MYID asc

어디에서 {last}내가 필요한 마지막 레코드의 행 번호 {length}로 대체되어야하며 필요한 행 수로 대체되어야합니다.last row - first row + 1 .

예를 들어 10에서 25 행 (완전히 16 행)을 원하면 {last}25 {length}가되고 25-10 + 1 = 16이됩니다.


다른 사람이 질문에 답하는 데 시간이 걸릴 때 반대표를 던지는 사람들을 경멸합니다.
jp2code

1

OPTIMIZE FOR n ROWS 절도 고려해야합니다. 이에 대한 자세한 내용은 SELECT 문 제한 지침 주제 의 DB2 LUW 문서에 있습니다 .

  • OPTIMIZE FOR 절은 결과의 서브 세트 만 검색하거나 처음 몇 행만 검색하는 데 우선 순위를 부여하려는 의도를 선언합니다. 그러면 옵티마이 저는 처음 몇 행을 검색하기위한 응답 시간을 최소화하는 액세스 플랜을 선택할 수 있습니다.

1

이 시도

SELECT * FROM
    (
        SELECT T.*, ROW_NUMBER() OVER() R FROM TABLE T
    )
    WHERE R BETWEEN 10000 AND 20000

0

DB2 테이블에서 효율적으로 페이지를 매기는 두 가지 솔루션이 있습니다.

1-row_number () 함수와 다른 게시물에 제시된 OVER 절을 사용하는 기술 ( "SELECT row_number () OVER (ORDER BY ...)"). 일부 큰 테이블에서 때때로 성능 저하를 발견했습니다.

2-스크롤 가능한 커서를 사용하는 기술. 구현은 사용 된 언어에 따라 다릅니다. 이 기술은 큰 테이블에서 더 강력 해 보입니다.

내년 세미나에서 PHP로 구현 된 두 가지 기술을 발표했습니다. 슬라이드는 다음 링크에서 사용할 수 있습니다. http://gregphplab.com/serendipity/uploads/slides/DB2_PHP_Best_practices.pdf

죄송하지만이 문서는 프랑스어로만 제공됩니다.


0

다음과 같은 사용 가능한 옵션이 있습니다.

DB2 has several strategies to cope with this problem.
You can use the "scrollable cursor" in feature.
In this case you can open a cursor and, instead of re-issuing a query you can FETCH forward and backward.
This works great if your application can hold state since it doesn't require DB2 to rerun the query every time.
You can use the ROW_NUMBER() OLAP function to number rows and then return the subset you want.
This is ANSI SQL 
You can use the ROWNUM pseudo columns which does the same as ROW_NUMBER() but is suitable if you have Oracle skills.
You can use LIMIT and OFFSET if you are more leaning to a mySQL or PostgreSQL dialect.  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.