:meta-keywords: rownum, inst_num, orderby_num, groupby_num :tocdepth: 3 *********** ROWNUM 함수 *********** ROWNUM, INST_NUM ================ .. c:macro:: ROWNUM .. function:: INST_NUM () **ROWNUM** 함수는 ì§ˆì˜ ê²°ê³¼ë¡œ ìƒì„±ë ê° ë ˆì½”ë“œì— ëŒ€í•œ 순서를 나타내는 번호를 반환한다. 첫 번째 ê²°ê³¼ ë ˆì½”ë“œëŠ” 1, ë‘ ë²ˆì§¸ ê²°ê³¼ ë ˆì½”ë“œëŠ” 2를 가진다. :rtype: BIGINT ì¼ë°˜ì ì¸ **SELECT** 문ì—서는 **ROWNUM**, **INST_NUM()**\ì„, **ORDER BY** ì ˆì„ í¬í•¨í•œ **SELECT** 문ì—서는 **ORDERBY_NUM()**\ì„, **GROUP BY** ì ˆì„ í¬í•¨í•œ **SELECT** 문ì—서는 **GROUPBY_NUM()**\ì„ ì‚¬ìš©í• ìˆ˜ 있다. **ROWNUM** 함수를 사용하면 질ì˜ì˜ ê²°ê³¼ ë ˆì½”ë“œ 수를 다양한 방법으로 ì œí•œí• ìˆ˜ 있다. 예를 들어, ì§ˆì˜ ê²°ê³¼ì˜ ì²˜ìŒ 10ê±´ë§Œ 조회한다거나, ì§ìˆ˜ 번째 ë˜ëŠ” 홀수 번째 ë ˆì½”ë“œë§Œ 반환하ë„ë¡ í• ìˆ˜ 있다. **ROWNUM** 함수는 ê²°ê³¼ íƒ€ìž…ì´ í° ì •ìˆ˜í˜•ì´ê³ , **SELECT** ì ˆê³¼ **WHERE** ì ˆê³¼ ê°™ì´ ì§ˆì˜ ë‚´ì— ìˆ˜ì‹ì´ ìœ„ì¹˜í• ìˆ˜ 있는 ëª¨ë“ ê³³ì— ì‚¬ìš©í• ìˆ˜ 있다. 하지만, **ROWNUM** 함수 결과를 ì†ì„± ë˜ëŠ” ì—°ê´€ëœ ë¶€ì§ˆì˜(correlated subquery)와 비êµí•˜ëŠ” ê²ƒì€ í—ˆìš©ë˜ì§€ 않는다. .. note:: * **WHERE** ì ˆì— ëª…ì‹œëœ **ROWNUM** 함수는 **INST_NUM()** 함수와 ê°™ì€ ì˜ë¯¸ë¥¼ 가진다. * **ROWNUM** 함수는 ê°ê°ì˜ **SELECT** ë¬¸ìž¥ì— ì¢…ì†ëœë‹¤. 즉, **ROWNUM** 함수가 부질ì˜ì— ì“°ì¸ ê²½ìš°, 부질ì˜ë¥¼ 수행하는 ë™ì•ˆì— ë¶€ì§ˆì˜ ê²°ê³¼ì— ëŒ€í•˜ì—¬ ì¼ë ¨ 번호를 반환한다. ë‚´ë¶€ì 으로, **ROWNUM** 함수 결과는 ì¡°íšŒëœ ë ˆì½”ë“œë¥¼ ì§ˆì˜ ê²°ê³¼ ì…‹ì— ì“°ê¸° ì§ì „ì— ìƒì„±ëœë‹¤. ì´ ìˆœê°„ì— ì§ˆì˜ ê²°ê³¼ ì…‹ì˜ ë ˆì½”ë“œì— ëŒ€í•œ ì¼ë ¨ 번호를 ìƒì„±í•˜ëŠ” ì¹´ìš´í„° ê°’ì´ ì¦ê°€ëœë‹¤. * **SELECT** ê²°ê³¼ì— ì¼ë ¨ë²ˆí˜¸ë¥¼ ë¶€ì—¬í• ëª©ì 으로 사용하는 경우, ì •ë ¬ ê³¼ì •ì´ ì—†ëŠ” 경우 **ROWNUM**\ì„, ORDER BY ì ˆì´ ìžˆìœ¼ë©´ **ORDERBY_NUM()** 함수를, GROUP BY ì ˆì´ ìžˆìœ¼ë©´ **GROUPBY_NUM()** 함수를 사용한다. * **SELECT** ë¬¸ì— **ORDER BY** ì ˆì´ í¬í•¨ëœ 경우 **WHERE** ì ˆì— ëª…ì‹œëœ **ORDERBY_NUM()** í•¨ìˆ˜ì˜ ê°’ì€ **ORDER BY** ì ˆ 처리를 위한 ì •ë ¬ ê³¼ì • ì´í›„ì— ìƒì„±ëœë‹¤. ì •ë ¬ ê³¼ì • ì´í›„ì— ê²°ê³¼ í–‰ì˜ ê°œìˆ˜ë¥¼ ì œí•œí•˜ë ¤ë©´ **FOR ORDERBY_NUM()** ì ˆì„ ì‚¬ìš©í•œë‹¤. * **SELECT** ë¬¸ì— **GROUP BY** ì ˆì´ í¬í•¨ëœ 경우 **HAVING** ì ˆì— ëª…ì‹œëœ **GROUPBY_NUM()** í•¨ìˆ˜ì˜ ê°’ì€ ì§ˆì˜ ê²°ê³¼ê°€ ê·¸ë£¹í™”ëœ ì´í›„ì— ìƒì„±ëœë‹¤. ê·¸ë£¹í™”ëœ ì´í›„ì— ê²°ê³¼ í–‰ì˜ ê°œìˆ˜ë¥¼ ì œí•œí•˜ë ¤ë©´ **HAVING GROUPBY_NUM()** ì ˆì„ ì‚¬ìš©í•œë‹¤. * ì •ë ¬ëœ ê²°ê³¼ í–‰ë“¤ì˜ ê°œìˆ˜ë¥¼ ì œí•œí•˜ëŠ” 목ì 으로 **FOR ORDERBY_NUM()** ë˜ëŠ” **HAVING GROUPBY_NUM()** 구문 ëŒ€ì‹ **LIMIT** ì ˆì„ ì‚¬ìš©í• ìˆ˜ 있다. * **ROWNUM** 함수는 **SELECT** 문 ë¿ë§Œ ì•„ë‹ˆë¼ **INSERT**, **DELETE**, **UPDATE** 와 ê°™ì€ SQL 문ì—ë„ ì“¸ 수 있다. 예를 들어, **INSERT INTO** *table_name* **SELECT** ... **FROM** ... **WHERE** ... 질ì˜ì™€ ê°™ì´ í•œ í…Œì´ë¸”ì˜ í–‰(row) 중 ì¼ë¶€ë¥¼ 조회하여 다른 í…Œì´ë¸”ì— ì‚½ìž…í•˜ê³ ìž í• ë•Œ, **WHERE** ì ˆì— **ROWNUM** 함수를 ì‚¬ìš©í• ìˆ˜ 있다. 다ìŒì€ *demodb* ì—서 1988 올림픽ì—서 금메달 개수를 기준으로 4위권 êµê°€ ì´ë¦„ì„ ë°˜í™˜í•˜ëŠ” ì˜ˆì œì´ë‹¤. .. code-block:: sql --Limiting 4 rows using ROWNUM in the WHERE condition SELECT * FROM (SELECT nation_code FROM participant WHERE host_year = 1988 ORDER BY gold DESC) AS T WHERE ROWNUM <5; :: nation_code ====================== 'URS' 'GDR' 'USA' 'KOR' LIMIT ì ˆì€ ì •ë ¬ëœ ê²°ê³¼ í–‰ì˜ ê°œìˆ˜ë¥¼ ì œí•œí•˜ë¯€ë¡œ ì•„ëž˜ì˜ ì§ˆì˜ ê²°ê³¼ëŠ” ìœ„ì˜ ê²°ê³¼ì™€ ë™ì¼í•˜ë‹¤. .. code-block:: sql --Limiting 4 rows using LIMIT SELECT ROWNUM, nation_code FROM participant WHERE host_year = 1988 ORDER BY gold DESC LIMIT 4; :: rownum nation_code ============================================ 143 'URS' 51 'GDR' 145 'USA' 78 'KOR' ì•„ëž˜ì˜ ROWNUM ì¡°ê±´ì€ ì •ë ¬ë˜ê¸° ì´ì „ì— í–‰ì˜ ê°œìˆ˜ë¥¼ ì œí•œí•˜ë¯€ë¡œ ì§ˆì˜ ê²°ê³¼ê°€ 위와 다르다. .. code-block:: sql --Unexpected results : ROWNUM operated before ORDER BY SELECT ROWNUM, nation_code FROM participant WHERE host_year = 1988 AND ROWNUM < 5 ORDER BY gold DESC; :: rownum nation_code ============================================ 1 'AFG' 2 'AHO' 3 'AND' 4 'ANG' ORDERBY_NUM =========== .. function:: ORDERBY_NUM () **ORDERBY_NUM()** 함수는 **ROWNUM** í˜¹ì€ **INST_NUM()** 함수와 함께, ê²°ê³¼ í–‰ë“¤ì˜ ê°œìˆ˜ë¥¼ ì œí•œí•˜ëŠ” 목ì 으로 사용ëœë‹¤. 단, ì°¨ì´ì ì€ **ORDER BY** ì ˆ ë’¤ì— ê²°í•©ë˜ì–´ 사용ë˜ê³ , ì´ë¯¸ ì •ë ¬ì„ ìˆ˜í–‰í•œ ê²°ê³¼ì— ëŒ€í•´ 순서를 부여한다는 ì ì´ë‹¤. 즉, **ORDER BY** ì ˆì´ í¬í•¨ëœ **SELECT** 문장ì—서 ì¡°ê±´ì ˆì— **ROWNUM** ì„ ì´ìš©í•˜ì—¬ ì¼ë¶€ ê²°ê³¼ 행들만 조회하는 경우, **ROWNUM** ì´ ë¨¼ì € ì ìš©ëœ í›„ **ORDER BY** ì— ì˜í•œ ì •ë ¬ì´ ìˆ˜í–‰ëœë‹¤. 반면, **ORDERBY_NUM()** 함수를 ì´ìš©í•˜ì—¬ ì¼ë¶€ ê²°ê³¼ 행들만 조회하는 경우, **ORDER BY** ì— ì˜í•œ ì •ë ¬ì´ ì´ë£¨ì–´ì§„ ê²°ê³¼ì— ëŒ€í•´ì„œ **ROWNUM** ì´ ì ìš©ëœë‹¤. :rtype: BIGINT 다ìŒì€ *demodb* ì˜ *history* í…Œì´ë¸”ì—서 3위ì—서 5ìœ„ê¹Œì§€ì˜ ì„ ìˆ˜ ì´ë¦„ê³¼ 기ë¡ì„ 조회하는 ì˜ˆì œì´ë‹¤. .. code-block:: sql --Ordering first and then limiting rows using FOR ORDERBY_NUM() SELECT ORDERBY_NUM(), athlete, score FROM history ORDER BY score FOR ORDERBY_NUM() BETWEEN 3 AND 5; :: orderby_num() athlete score ================================================================== 3 'Luo Xuejuan' '01:07.0' 4 'Rodal Vebjorn' '01:43.0' 5 'Thorpe Ian' '01:45.0' ì•„ëž˜ì˜ LIMIT ì ˆì„ ì‚¬ìš©í•œ 질ì˜ëŠ” ìœ„ì˜ ì§ˆì˜ì™€ ë™ì¼í•œ 결과를 ì¶œë ¥í•œë‹¤. .. code-block:: sql SELECT ORDERBY_NUM(), athlete, score FROM history ORDER BY score LIMIT 2, 3; ì•„ëž˜ì˜ ROWNUMì„ ì‚¬ìš©í•˜ì—¬ ê²°ê³¼ í–‰ì˜ ê°œìˆ˜ë¥¼ ì œí•œí•œ 질ì˜ëŠ” ì •ë ¬ ì´ì „ì— ê°œìˆ˜ë¥¼ ì œí•œí•œ ì´í›„ì— ORDER BY ì •ë ¬ì„ ìˆ˜í–‰í•œë‹¤. .. code-block:: sql --Limiting rows first and then Ordering using ROWNUM SELECT ROWNUM athlete, score FROM history WHERE ROWNUM BETWEEN 3 AND 5 ORDER BY score; :: athlete score ============================================ 'Thorpe Ian' '01:45.0' 'Thorpe Ian' '03:41.0' 'Hackett Grant' '14:43.0' GROUPBY_NUM =========== .. function:: GROUPBY_NUM () **GROUPBY_NUM()** 함수는 **ROWNUM** í˜¹ì€ **INST_NUM()** 함수와 함께, ê²°ê³¼ í–‰ë“¤ì˜ ê°œìˆ˜ë¥¼ ì œí•œí•˜ëŠ” 목ì 으로 사용ëœë‹¤. 단, ì°¨ì´ì ì€ **GROUP BY** ... **HAVING** ì ˆ ë’¤ì— ê²°í•©ë˜ì–´ 사용ë˜ë©°, ì´ë¯¸ ì •ë ¬ì„ ìˆ˜í–‰í•œ ê²°ê³¼ì— ëŒ€í•´ 순서를 부여한다는 ì ì´ë‹¤. ë˜í•œ, **INST_NUM()** 함수는 스칼ë¼(scalar) 함수ì´ì§€ë§Œ, **GROUPBY_NUM()** 함수는 집계 í•¨ìˆ˜ì˜ ì¼ì¢…ì´ë‹¤. 즉, **GROUP BY** ì ˆì´ í¬í•¨ëœ **SELECT** 문장ì—서 ì¡°ê±´ ì ˆì— **ROWNUM** ì„ ì´ìš©í•˜ì—¬ ì¼ë¶€ ê²°ê³¼ 행들만 조회하는 경우, **ROWNUM** ì´ ë¨¼ì € ì ìš©ëœ í›„ **GROUP BY** ì— ì˜í•œ 그룹 ì •ë ¬ì´ ìˆ˜í–‰ëœë‹¤. 반면, **GROUPBY_NUM()** 함수를 ì´ìš©í•˜ì—¬ ì¼ë¶€ ê²°ê³¼ 행들만 조회하는 경우, **GROUP BY** ì— ì˜í•œ 그룹 ì •ë ¬ì´ ì´ë£¨ì–´ì§„ ê²°ê³¼ì— ëŒ€í•´ì„œ **ROWNUM** ì´ ì ìš©ëœë‹¤. :rtype: BIGINT 다ìŒì€ *demodb* ì˜ *history* í…Œì´ë¸”ì—서 과거 5ê°œì˜ ì˜¬ë¦¼í”½ì— ëŒ€í•´ì„œ 최단 기ë¡ì„ 조회하는 ì˜ˆì œì´ë‹¤. .. code-block:: sql --Group-ordering first and then limiting rows using GROUPBY_NUM() SELECT GROUPBY_NUM(), host_year, MIN(score) FROM history GROUP BY host_year HAVING GROUPBY_NUM() BETWEEN 1 AND 5; :: groupby_num() host_year min(score) ========================================================= 1 1968 '8.9' 2 1980 '01:53.0' 3 1984 '13:06.0' 4 1988 '01:58.0' 5 1992 '02:07.0' ì•„ëž˜ì˜ LIMIT ì ˆì„ ì‚¬ìš©í•œ 질ì˜ëŠ” ìœ„ì˜ ì§ˆì˜ì™€ ë™ì¼í•œ 결과를 ì¶œë ¥í•œë‹¤. .. code-block:: sql SELECT GROUPBY_NUM(), host_year, MIN(score) FROM history GROUP BY host_year LIMIT 5; ì•„ëž˜ì˜ ROWNUMì„ ì‚¬ìš©í•˜ì—¬ ê²°ê³¼ í–‰ì˜ ê°œìˆ˜ë¥¼ ì œí•œí•œ 질ì˜ëŠ” 그룹핑 ì´ì „ì— ê°œìˆ˜ë¥¼ ì œí•œí•œ ì´í›„ì— GROUP BY ì •ë ¬ì„ ìˆ˜í–‰í•œë‹¤. .. code-block:: sql --Limiting rows first and then Group-ordering using ROWNUM SELECT host_year, MIN(score) FROM history WHERE ROWNUM BETWEEN 1 AND 5 GROUP BY host_year; :: host_year min(score) =================================== 2000 '03:41.0' 2004 '01:45.0'