mysql의 LIMIT 와 같은 결과 얻기....

작성자 정보

  • 달건 작성
  • 222.♡.209.119 아이피
  • 작성일

컨텐츠 정보

본문

제목 : mysql의 LIMIT 와 같은 결과 얻기....  
-----------------------------------------------------------------------------
** 순차 데이타 정렬을 통해서 임의의 중간 일부분의 데이타를 가져오는 방법
MS-SQL 에서는 MYSQL 처럼 LIMIT 가 없으므로 
변칙 수법을 이용해야 한다. 

불행중 다행으로 
MS-SQL 에서는 TOP 을 이용해서 상위 몇 행을 얻을 수 있다. 

SQL 에서 부질의를 사용할 수 있는데 

임의의 테이블이 다음과 같을 때,

TABEL NAME : USER_INFO
FIELD    TYPE
------------------------
USER_ID    VARCHAR(10)
AGE		INT
ADDRESS    VARCHAR(100)



[1] SELECT * FROM USER_INFO WHERE USER_ID IN (SELECT USER_ID FROM 
USER_INFO WHERE AGE > 10 )
위의 [1] 은 다음과 같다.
SELECT * FROM USER_INFO WHERE AGE > 10

만약 , 다음과 같은 QUERY를 사용한다면

즉 , NOT IN 을 사용한다.

[2] SELECT * FROM USER_INFO WHERE USER_ID NOT IN (SELECT USER_ID FROM
USER_INFO WHERE AGE > 10 )
 
[1]의 결과는 10 살 이상인 사용자 정보를 얻는 것이고
[2]의 결과는 10 살 이상인 사용자를 제외한 사람들을 얻는 것이다.

[1] , [2] 를 통해서 SUB QUERY 의 용도는 대충 알 수 있다.
그러면 , 어떻게 해서

어떤 조건에 맞는 ( 조건이 있는) 데이타 중에서 원하는 중간의 데이타를 얻을 수 있을까???

가상의 순서   데이타
1              .......
2             ......
3             ......
4             ......
5             .....
6        ......
.

MS-SQL 에서 TOP 이라는 놈을 사용하면
출력된 결과셋(RESULTSET) 에서

원하는 만큼의 행을 얻을 수 있다.

즉 ,[3] SELECT TOP 10 * FROM USER_INFO WHERE AGE >  10

위의 QUERY 는 10살 이상인 사용자들을 대상으로
상위 10 명에 대한 정보만을 얻어서 CLIENT ( APPLICATION) 에 돌려 주게 된다.

만약 ,[3]의 QUERY에 ORDER BY USER_ID 를 사용한다면 , 언제나 같은 순서로 데이타를 얻
을 것이다.

[4]  SELECT TOP 10 * FROM USER_INFO WHERE AGE >  10 ORDER BY USER_ID

이제 한 발짝  더 나아가서 ,
[1]의 query에 top 을 추가한 결과는 어떻게 될까

[1] SELECT * FROM USER_INFO WHERE USER_ID IN (SELECT USER_ID FROM
USER_INFO WHERE AGE > 10 ORDER BY USER_ID)

==>[5] SELECT * FROM USER_INFO WHERE USER_ID IN (SELECT top 10 USER_ID FROM
USER_INFO WHERE AGE > 10 ORDER BY USER_ID)

[6] SELECT TOP 3 * FROM USER_INFO WHERE USER_ID IN (SELECT top 10 USER_ID
FROM USER_INFO WHERE AGE > 10 ORDER BY USER_ID)

[5]는 10살 이상의 사용자들을 정렬해서 상위 10명의 정보를 가져온다.
[6]은 [5] 에서 얻은 사용자들 중에서 상위 3명의 정보를 얻는다.

 
만약 , 다음과 같이 한다면 ,

[7] SELECT TOP 3 * FROM USER_INFO
WHERE USER_ID NOT IN (SELECT top 10 USER_ID FROM USER_INFO WHERE AGE > 10
ORDER BY USER_ID)

아주 중요한 부분인데 ,
[7]의 결과는 10살 이상인 사용자들 중에서 상위 10 번째 다음인 11, 12 ,13 번째 행의 데이타를
얻을 것으로 생각하기 쉽다.
그러나 위의 결과는 그렇지 않다.
위의 결과는 SUB QUERY에서 얻은 사용자를 제외한 모든 사용자가 된다.
따라서 상위 3명에 대해 얻은결과에는 10살 이하의 사용자도 포함된다.

결론 ,

말이 길어졌는데.

우리는 TABLE에서 어떤 조건을 만족하는 결과를 만들고
이 결과에서 상위 몇 행을 제외한 그 다음 행에서 부터 원하는 행 만큼 데이타를 가져오려한다.

예로 ,
(1)10살 이상의 사용자 라는 조건을 만족하는 결과
이것은 다음과 같다.
=> SELECT * FROM USER_INFO WHERE AGE > 10
(2) 이결과  집합에서 상위 10명
=> SELECT TOP 10 * FROM USER_INFO WHERE AGE > 10

(3) 이 10명을 제외한 사용자들
=>  SELECT  * FROM USER_INFO

WHERE USER_ID NOT IN (SELECT top 10 USER_ID FROM USER_INFO WHERE AGE > 10 )

(4) (3)에서 얻은 결과집합에는 10살 이하도 있다. 따라서 이들은 조건에 맞지 않으므로

=> SELECT  * FROM USER_INFO
   WHERE USER_ID NOT IN
                (SELECT top 10 USER_ID FROM USER_INFO WHERE AGE > 10 )
   AND  AGE > 10

*** (4) 의 QUERY 를 자세히 보면 WHERE 절의 조건이 서로 같은 것을 알 수 있다.
        또한 SUB QUERY 에서 얻은 결과를 MAIN QUERY에서 조건의 일부로 사용하고 있음을
알 수 있다.

    위의 QUERY를 분석하면 다음과 같다.
  10살 이상인 사용자들 중에서 상위 10명을 제외한 모든 사용자들의 정보를 얻어라!!!


결국, 10살 이상(조건)의 사용자들중에서   11번째에서 15번째의 데이타를 얻기 위해서는

(4) 의 QUERY 에 TOP 을 한번 더 사용해서

(5)=> SELECT TOP 5 * FROM USER_INFO
   WHERE USER_ID NOT IN (SELECT top 10 USER_ID FROM USER_INFO WHERE AGE >
10 )
   AND  AGE > 10

(5)의 결과는 결국 우리가 얻으려는 11번째 에서 15번째의 데이타이다.
물론 조건도 만족한다. ( 10살 이상)

UPDATE QUERY ( INSERT , DELETE , UPDATE) 등의 연산으로부터  정확한 데이타를 얻으
려면

다음과 같이 하면 된다.

   SELECT TOP 5 * FROM USER_INFO
   WHERE USER_ID NOT IN (SELECT top 10 USER_ID FROM USER_INFO WHERE AGE >
10 ORDER BY USER_ID)
   AND  AGE > 10 ORDER BY USER_ID

[마무리]

조건을 만족하는 데이타 중에서
중간의 데이타를 얻기위한 방법 *** 중요한 것은 조건이 두번 들어 간다는 것이다.

SELECT TOP [얻으려는 행의수] * FROM [TABLE]
WHERE [PRIMARY KEY] NOT IN ( SELECT TOP [중간의 시작위치 - 1] [PRIMARY KEY]
FROM [TABLE] WHERE [조건] ORDER BY [PRIMARY KEY])
AND [조건] ORDER BY [PRIMARY KEY]


지금까지 알아본 QUERY 는 매우 중요하다고 할 수 있다.
이유는 DB 서버에서의 부하를 줄이는 것도 중요하지만 ,
만약 , 위와 같이 중간의 데이타를 얻는 방식이 아닌 , 전체의 데이타를 RESULTSET으로 얻어

NEXT 로 해당 위치를 찾는다면 ,
그 폐단은 다음과 같다.
(1)DB 서버 에서 CLIENT(APPLICATION) 까지  NETWORK 을 통해서
   전체의 데이타가 전송되어야 하므로 CLIENT 와 DB SERVER간의 NETWORK 부하가 걸린
다.
(2)얻은 결과를 CLIENT 에서 사용하기 위해서는 우선 메모리를 그 데이타의 양만큼 잡아 주어
야 하므로
RESOURCE 를 낭비하게 된다.

(3) NEXT 를 통해서 해당 위치 (중간 시작위치) 까지 가기 위한 CPU 사용의 비효율성 ,

등등, 이러한 문제 점들은 전체 SYSTEM의 성능을 저하시키고 RESOURCE 를 낭비하게 되므


심각하게는 SYSTEM DOWN 이라는 최악의 상황으로 이어질 수 있다.


 

관련자료

댓글 0
등록된 댓글이 없습니다.

최근글


  • 글이 없습니다.

새댓글


  • 댓글이 없습니다.
알림 0