SQL 프로그래머스 | 상위 N개 레코드 | LIMIT 사용 | ROWNUM, ROW_NUMBER() | MIN(날짜) | RANK() 윈도우 함수 | 셀프조인 | FETCH FIRST ~ ROW(S)

    728x90

     

    상위 n개 레코드

    https://school.programmers.co.kr/learn/courses/30/lessons/59405

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

    동물 보호소에 가장 먼저 들어온 동물의 이름을 조회하는 SQL 문을 작성해주세요.

     

    ▼ LIMIT 사용

    SELECT NAME
    FROM ANIMAL_INS
    ORDER BY DATETIME LIMIT 1

     

    동물 보호소에 들어온 일자(날짜)오름차순 정렬하면

    날짜가 과거인 것부터 시작해서 최근 것까지 시간 순서대로 정렬

    그 뒤 LIMIT으로 조회할 행을 제한해주면 

    가장 먼저 들어온 동물의 이름을 조회할 수 있게 됨

     


    ▼ WHERE절 서브쿼리 MIN(날짜)

    SELECT NAME
    FROM ANIMAL_INS
    WHERE DATETIME = (SELECT MIN(DATETIME) MIN_DATE FROM ANIMAL_INS)

     

    WHERE절의 서브쿼리

    동물보호소에 들어온 일자(날짜)가 가장 작은 것을 조회해서 구할 수도 있음

    MIN(날짜데이터) 하게 되면 가장 '과거' 일자의 행이 뽑히게 됨

    메인쿼리에서 그 과거일자에 해당하는 이름을 조회해주면 끝


    ▼ Oracle의 ROWNUM 사용

    SELECT NAME
    FROM (
        SELECT *
        FROM ANIMAL_INS
        ORDER BY DATETIME ASC)
    WHERE ROWNUM = 1;

     

    Oracle 사용자의 경우 ROWNUM을 이용해서 행 번호가 1인 것만 뽑아내는 것을 발견!

    그래서 혹시 MySQL로도 되는지 확인해봤는데 계속 오류가 나서 찾아보니

    MySQL의 경우에는 ROW_NUMBER() 라는 게 있었음

     

    ※ 참고로 위 쿼리문에서 FROM절 서브쿼리를 사용한 이유

    쿼리문의 실행 순서 때문임

    만약 서브쿼리를 사용하지 않게 되면

    WHERE ROWNUM=1 뒤에

    ORDER BY절이 오게 될 텐데

    그러면 아직 날짜 별로 정렬되지 않은 상태에서

    일단 행 번호가 1인 것을 뽑은 뒤에

    오름차순 정렬이 일어나서

    문제에서 요구하는 '보호소에 가장 먼저 들어온 동물'이 조회되는 게 아니라

    어떤 임의의 한 행 값이 조회될 것


    ▼ MySQL의 ROW_NUMBER() 사용

    SELECT ROW_NUMBER() OVER(ORDER BY DATETIME) ROWNUM, NAME
    FROM ANIMAL_INS
    LIMIT 1

     

    MySQL에 있는 ROW_NUMBER()를 사용해 봄

    ROW_NUMBER()을 사용하게 되면 행 번호를 붙여서 조회 하게 됨

    그래서 결과과 이름만 조회되진 않고, 행번호 + 이름의 조합으로 조회됨

     

    SELECT NAME
    FROM (
        SELECT NAME, 
        ROW_NUMBER() OVER(ORDER BY DATETIME) AS rnum 
        FROM ANIMAL_INS
    ) RNUM
    where RNUM.rnum < 2

     

    위 문제를 해결하기 위해

    ROW_NUMBER() FROM절의 서브쿼리로 넣어준 뒤에

    메인쿼리에 조건을 줘서 이름만 조회하면 끝!

     

    [참고 게시글] ROW_NUMBER() 사용방법

    https://solbel.tistory.com/2242 

     

    [sql/mysql] mysql row_number() 사용해서 행번호 붙이는 방법

    [sql/mysql] mysql row_number() 사용해서 행번호 붙이는 방법 mysql 에서 특정 테이블의 행번호를 붙여서 데이터를 조회하고 싶은 경우가 있습니다. 그럴때는 아래 나와있는 row_number 를 사용하시면 됩니

    solbel.tistory.com


    ▼ RANK() 윈도우 함수 사용

    SELECT NAME
    FROM(
        SELECT NAME, RANK() OVER(ORDER BY DATETIME ASC) RN
        FROM ANIMAL_INS
    ) A
    WHERE A.RN = 1

     

    이 문제를 RANK() 윈도우 함수로 푼 사람도 있었음

    날짜를 오름차순한 결과순위를 지정해준 뒤

    FROM절의 서브쿼리에 넣어줌.

    그 후 메인쿼리WHERE 조건절에서 이름을 하나만 뽑게 만듦

     

    [참고 게시글]

    윈도우 함수에 대해 궁금하신 분들은 클릭!

    [IT 교육/SQL] - SQL | 윈도우 함수(Window Function) 사용법 정리 | RANK함수, SUM함수

     

    SQL | 윈도우 함수(Window Function) 사용법 정리 | RANK함수, SUM함수

    0. 윈도우 함수(Window Function)는 다중행 함수 ▶ 다중 행 함수(Multi-Row Function) : 여러 행의 그룹에 대해 적용되는 함수 ▶ 다중 행 함수의 종류(그룹함수, 윈도우 함수) 1) 그룹함수 (집계함수, 고급

    nasena.tistory.com


    ▼ 셀프조인 사용

    SELECT B.NAME 
    FROM 
    (SELECT MIN(DATETIME) DT
     FROM ANIMAL_INS A)
     A, ANIMAL_INS B 
    WHERE A.DT = B.DATETIME

     

     

    셀프조인까지 등장하다니,,!

    다른 분들 답을 보면 내가 생각하지 못한 다양한 풀이 방법이 있어서 놀랍다.

    셀프 조인은 말 그대로 자신과 자신의 조인으로

    이 분은 FROM절 서브쿼리에서 MIN(날짜)를 구한 뒤에

    메인쿼리에서 그 날짜가 또 다른 자신의 DATETIME과 같으면

    이름을 조회하도록 만들었음

     

    그런데 이렇게

    FROM절에 사용할 테이블 두 개를 다 적어줘도 되는 거였구나.. 

    조인이라는 게 JOIN ~ ON 이런 걸 꼭 써줘야만 하는 줄 알았는데

    셀프조인 시에는 꼭 그런 것도 아닌가보다

     

    [참고게시글] 셀프조인

    https://moonpiechoi.tistory.com/124

     

    [SQL] 셀프 조인(SELF JOIN)

    셀프 조인이란, 동일 데이블 사이의 조인을 말한다. FROM 절에 동일 테이블이 두 번 이상 나타난다. 같은 테이블끼리 조인하는 것이므로 별칭(ALIAS)을 꼭 사용해야 한다. 예시 SELECT A.EMPNO 사원번호,

    moonpiechoi.tistory.com


    ▼ (참고) Oracle의 FETCH  FIRST ~ ROW(S) ONLY 사용

    SELECT NAME FROM ANIMAL_INS
    ORDER BY DATETIME
    FETCH FIRST 1 ROW ONLY;
    
    FETCH FIRST ~ ROW(S) ONLY를 통해 서브쿼리 없이 첫 ~ row를 반환하게 할 수 있습니다.

     

    Oracle에서 서브쿼리 없이 첫 행을 조회하고 싶은 분들은 참고!

    (오라클 12c 부터 사용 가능하다고 함)

     

    [참고 게시글]

    ROWNUM 과 FECTCH FIRST ~ ROW(S) 비교

    https://dobby-codeup.tistory.com/7

     

    [ORACLE]ROWNUM VS FETCH FIRST ROWS사용법

    회사에서 쿼리를 짜다보면 여러 데이터 중에서 최상단 n개를 출력해달라는 요청이 왕왕 있다. 나는 대게 FETCH FIRST ROWS를 사용하는게 편해서 실제 자주 사용하고 있는데, 이번 글에서 ROWNUM 과 FETCH

    dobby-codeup.tistory.com

     

    [참고 게시글]

    FETCH구문 더 자세히 알아보고싶은 분들 클릭!

    https://rimkongs.tistory.com/158

     

    [Oracle] FETCH 구문 사용하기

    Oracle 12c release부터 사용할 수 있는 구문이다. 다음과 같이 다대일 관계를 형성하고 있는 INVENTORIES 와 PRODUCTS 테이블을 보자 quantity 컬럼에 대해 top-5를 리턴해준다. SELECT product_name, quantity FROM invento

    rimkongs.tistory.com

     

    728x90

    댓글