SQL: SELECT

yongseok·2023년 2월 26일
0

DATABASE

목록 보기
1/2

엑셀의 함수를 잘 다루고, MySQL을 사용한 경험이 있지만 프로그래머스의 문제가 풀리지 않았고, 작성했던 쿼리들의 효율에 의문이 있었다.

처음으로 Oracle을 사용해보면서 총 6일간 학습해 문제를 해결해 프로그래머스에서 제공하고 있는 SQL(71개) 문제를 모두 해결할 수 있었다.

앞으로 SQL을 잘 활용하기 위해 사용했던 문법과 함수를 정리하고자한다.

SQL 문법 구조

SELECT

  • 데이터베이스에 보관되어 있는 데이터를 조회하는 데 사용
  • 조회할 열이나 여러 열에 저장된 데이터의 조합 또는 연산식을 지정

DISTINCT

  • 열 이름을 명시하기 전에 선택적으로 사용해 중복을 제거 링크
    SELECT COUNT(DISTINCT NAME)
    FROM animal_ins
    WHERE name IS NOT NULL;

AS

  • 최종 출력되는 열 이름을 임의로 지정할 수 있는 별칭(alias)은 4가지 방법으로 사용가능
    • MAX(DATETIME) time
    • MAX(DATETIME) "time"
    • MAX(DATETIME) AS time * 가장 많이 사용되는 형태
    • MAX(DATETIME) AS "time"
  • 별칭은 WHERE, GROUP BY에서 사용할 수 없다. (최종출력과, ORDER BY 용도로 보자)
  • 작은 따옴표를 사용하면 에러(ORA-00923: FROM keyword not found where expected)가 발생 링크
    SELECT MAX(DATETIME) AS 시간
    FROM ANIMAL_INS;

DECODE

  • 기준이 되는 데이터를 먼저 지정한 후 해당 데이터 값에 따라 다른 결과 값을 내보내는 함수
  • 유사 SWITCH-CASE
    DECODE(검사 대상이 될 열 또는 데이터, 연산이나 함수의 결과,
        조건1, 데이터가 조건1과 일치할 때 반환할 결과,
        조건2, 데이터가 조건2와 일치할 때 반환할 결과,
        ...
        조건n, 데이터가 조건n과 일치할 때 반환할 결과,
        위 조건1~조건n과 일치한 경우가 없을 때 반환할 결과
    )

CASE

  • 각 조건에 따라 반환할 데이터를 설정할 때 사용하는 함수
  • 유사 IF~ELSE IF ~ELSE
    CASE
        WHEN 조건1 THEN 조건1의 결과 값이 TRUE일 때 반환
        WHEN 조건2 THEN 조건2의 결과 값이 TRUE일 때 반환
        ...
        WHEN 조건n THEN 조건n의 결과 값이 TRUE일 때 반환
        ELSE 위 조건1~조건n과 일치하는 경우가 없을 때 반환
    END
  • CASE WHEN ~ THEN ~ LESE ~ END 문법을 알고 있는게 좋다. 링크
    SELECT order_id,product_id,TO_CHAR(out_date,'YYYY-MM-DD') AS out_date, (
        CASE WHEN out_date IS NULL THEN '출고미정'
            WHEN out_date<TO_DATE('20220502','YYYYMMDD') THEN '출고완료' 
            ELSE '출고대기' END) AS 출고여부
    FROM food_order
    ORDER BY order_id;

FROM

  • 조회할 데이터가 저장된 테이블 이름을 명시
  • 테이블, 뷰 모두 올수 있는 자리로 서브쿼리를 사용해 인라인 뷰를 넣어주는 경우도 많다. 링크
    SELECT flavor
    FROM (
        SELECT flavor, SUM(total_order) AS total_order
        FROM(
            SELECT *
            FROM first_half
            UNION ALL
            SELECT *
            FROM july
        )
        GROUP BY flavor
        ORDER BY total_order DESC
    )
    WHERE ROWNUM < 4;

JOIN

  • 두 개 이상의 테이블을 연결하여 하나의 테이블처럼 출력할 때 사용하는 방법
  • 컬럼이름이 중복되는 경우 별칭이 필수적임

INNER JOIN

  • 테이블을 연결한 후에 출력행을 각 테이블의 특정열에 일치한 데이터를 기준으로 선정하는 방식
  • 등가조인, 단순조인, 심플 조인 등으로 불림

SELF JOIN

  • 하나의 테이블을 여러 개의 테이블 처럼 활용하여 조인하는 방식

OUTER JOIN(LEFT JOIN)

  • 조인 조건 데이터 중 어느 한쪽이 NULL임에도 결과를 출력하여 포함시켜야 하는 경우
  • 대부분 문제는 레프트 조인으로 해결가능하다. (우선 하나라도 익숙해지자!) 링크
    SELECT ai.animal_id, ai.name 
    FROM animal_ins ai 
        LEFT JOIN animal_outs ao
        ON ai.animal_id=ao.animal_id
    WHERE ai.datetime>ao.datetime
    ORDER BY ai.datetime;

WHERE

  • SELECT문으로 데이터를 조회할 때 특정 조건을 기준으로 원하는 행을 출력하는데 사용
  • 여러 연산자를 함께 사용하면 더욱 세밀하게 데이터 검색이 가능
  • MAX, MIN, COUNT 등의 함수를 조건에 바로 사용할 수 없고 다른 서브쿼리를 사용할 수 있다. 링크
    SELECT *
    FROM places
    WHERE host_id IN (
        SELECT host_id 
        FROM places
        GROUP BY host_id
        HAVING COUNT(*) >= 2
    )
    ORDER BY id;

GROUP BY

  • 데이터를 그룹화 하여 의미있는 결과를 열 값별로 묶어서 출력하는데 사용
  • ~별이란 키워드가 보인다면 정말 많이 사용되기 때문에 숙지 필요
  • 테이블에 출력가능한 값은 크게 2종류 링크
    • GROUP BY에 들어가는 컬럼

    • 다중행 함수(SUM, COUNT, MIN, MAX 등)를 적용한 칼럼

      SELECT animal_type, COUNT(*)
      FROM animal_ins 
      WHERE animal_type = 'Cat' OR animal_type = 'Dog'
      GROUP BY animal_type
      ORDER BY animal_type;

HAVING

  • GROUP BY 절을 통해 그룹화된 결과 값의 범위를 제한하는 데 사용
  • WHERE(레코드를 제한함) 와 차이를 잘 알고 사용하기 링크
    SELECT cart_id
    FROM cart_products
    WHERE name IN ('Milk','Yogurt')
    GROUP BY cart_id
    HAVING COUNT(DISTINCT name)=2
    ORDER BY cart_id ASC;

ROLLUP, CUBE, GROUPING SETS

  • 당장 활용도가 낮다.

ORDER BY

  • 데이터를 정렬된 상태로 출력하기 위해 사용
    • 오름차순 ASC
    • 내림차순 DESC
  • ORDER BY절은 정렬 로직으로 시간적 비용이 큰 작업이다.
  • 문제에서는 컬럼과 정렬에 대한 부분만 잘 확인하면 된다. 링크
    SELECT flavor
    FROM first_half 
    ORDER BY total_order DESC, shipment_id;

N개 레코드

  • Oracle은 MySQL과 달리 LIMIT를 사용할 수 없다.
  • 서브쿼리에서 정렬을 선행하고 ROWNUM을 사용해 해결한다. 링크
    SELECT *
    FROM (
        SELECT ai.name, ai.datetime
        FROM animal_ins ai LEFT JOIN animal_outs ao
        ON ai.animal_id = ao.animal_id
        WHERE ao.animal_id IS NULL
        ORDER BY ai.datetime
    )
    WHERE ROWNUM < 3

SUBQUERY

  • SQL문 실행에 필요한 데이터를 추가로 조회하기 위해 SQL문 내부에서 사용하는 SELECT문을 의미
    SELECTFROM 테이블
    WHERE 조건식 (
        SELECTFROM 테이블
        WHERE 조건식);
  • 단일행 연산자: >, >=, =, <=, <, <>, ^=, !=
  • 다중행 연산: IN, ANY, SOME, ALL, EXISTS
  • SELECT, FROM, WHERE절에 각각 사용 가능하다.
  • 예전에 해결하지 못한 것들을 쉽게 해결할 수 있도록 만들어줬다. 링크
    SELECT mp.member_name, rr.review_text, TO_CHAR(rr.review_date,'YYYY-MM-DD') AS review_date
    FROM REST_REVIEW rr 
        LEFT JOIN MEMBER_PROFILE mp
        ON rr.member_id = mp.member_id
    WHERE mp.member_id IN (
        SELECT member_id
        FROM (
            SELECT member_id, COUNT(*) AS count_review
            FROM rest_review
            GROUP BY member_id
            ORDER BY count_review DESC
        )
        WHERE count_review = (
            SELECT count_review
            FROM (
                SELECT member_id, COUNT(*) AS count_review
                FROM rest_review
                GROUP BY member_id
                ORDER BY count_review DESC
            )
            WHERE ROWNUM = 1)
        )
    ORDER BY rr.review_date, review_date;

SQL 연산자

AND, OR 연산자

  • 여러 조건식을 지정하기 위해 사용하는 논리 연산자

AND

  • AND 연산의 결과
    • TRUE AND TRUETRUE
    • TRUE AND FALSEFALSE
    • FALSE AND TRUEFALSE
    • FALSE AND FALSEFALSE

OR

  • OR 연산의 결과
    • TRUE OR TRUETRUE
    • TRUE OR FALSETRUE
    • FALSE OR TRUETRUE
    • FALSE OR FALSEFALSE

논리부정 연산

  • NOT
    • NOT TRUE → FALSE
    • NOT FALSE → TRUE

산술 연산자

  • +, -, *, /
  • NULL과 연산시 NULL이 나오니 주의

비교 연산자

대소비교

  • >, >=, <=, <
  • NUMBER, STRING, DATE 모두 비교가 가능

등가비교

  • 같다: =
  • 같지 않다: !=, <>, ^=

BETWEEN A AND B

  • 특정 열 값의 최소-최고 범위를 지정하여 해당 범위 내 데이터를 조회하는 경우 간단히 표현 링크
    SELECT COUNT(*)
    FROM user_info
    WHERE TO_CHAR(joined,'YY')='21' 
        AND age BETWEEN 20 AND 29;

IN 연산자

  • 특정 열에 해당하는 조건을 여러 개 지정시 사용
    SELECT [조회할 열1 이름], ...
    FROM [조회할 테이블 이름]
    WHERE 열 이름 IN (데이터1,...)
  • NOT IN 을 통해서 제외한 결과를 얻을 수도 있다.
  • 내부에 스트링으로 넣어주어도 되고, 서브쿼리를 사용해도 된다. 링크
    SELECT ANIMAL_ID,	NAME,	SEX_UPON_INTAKE
    FROM animal_ins
    WHERE name IN ('Lucy', 'Ella', 'Pickle', 'Rogan', 'Sabrina', 'Mitty')
    ORDER BY animal_id;
  • 다중열 서브쿼리를 활용해 2개의 조건에 적용할 수도 있다. 링크
    SELECT category, price AS max_price, product_name
    FROM food_product
    WHERE (category,price) IN (
        SELECT category, MAX(price) AS max_price
        FROM food_product
        WHERE category IN ('과자', '국', '김치', '식용유')
        GROUP BY category
    )
    ORDER BY price DESC;

LIKE 연산자와 와일드카드

LIKE

  • 일부 문자열이 포함된 데이터를 조회할 때 사용
  • NOT LIKE 사용가능

와일드카드

  • 특정 문자 또는 문자열을 대체하거나 문자열 데이터와 패턴을 표기하는 특수문자
    • _: 어떤 값이든 상관없이 한 개의 문자 데이터
    • %: 길이와 상관 없이(문자 없는 경우도 포함) 모든 문자 데이터를 의미
  • LIKE '%S': 전방일치
  • LIKE 'S%': 후방일치
  • LIKE '%S%': 부분일치 링크
    SELECT car_type, COUNT(*) AS cars
    FROM car_rental_company_car
    WHERE options LIKE '%시트%'
    GROUP BY car_type
    ORDER BY car_type;

NULL 연산자

  • NULL은 데이터 값이 완전히 비어있는 상태
    • 값이 존재하지 않음, 해당 사항 없음, 노출할 수 없는 값, 확정되지 않은 값

IS NULL

  • 특정 열 또는 연산의 결과 값이 NULL인지 여부를 확인하기 위한 연산자
  • 값이 NULL인지 확인하는 방법으로 IS NULL사용한다. 링크
    SELECT animal_id
    FROM animal_ins
    WHERE name IS NULL
    ORDER BY animal_id;

IS NOT NULL

  • 값이 NULL이 아닌지 확인하는 방법으로 IS NOT NULL을 사용한다. 링크
    SELECT animal_id
    FROM animal_ins
    WHERE name IS NOT NULL
    ORDER BY animal_id;

집합연산자

  • 1개 이상의 SELECT 문을 통해 데이터를 조회한 결과를 하나의 집합과 같이 다룰 수 있는 연산자
    • UNION : 결과 값을 합집합으로 묶어줌. 결과 중복 제거 후 출력
    • UNION ALL: 결과 값을 합집합으로 묶어줌. 결과 중복 값도 출력
    • MINUS: 차집합 처리. 선행 SELECT문의 값 중 후행 SELECT에 존재하지 않는 데이터만 출력
    • INTERSECT: 교집합 처리. 선행 SELECT문과 후행 SELECT에 모두 존재하는 데이터만 출력

UNION

  • 합집합을 의미하는 연산자
  • 출력하려는 열 개수와 각 열의 자료형이 순서별로 일치해야함(열의 이름은 무관)
    • 선행 SELECT 문의 컬럼명, 순서를 따라간다.

    • NULL AS user_id 꼴로 NULL 컬럼을 생성해 개수를 맞출 수 있다. 링크

      SELECT *
      FROM(
          SELECT TO_CHAR(sales_date,'YYYY-MM-DD') AS sales_date, product_id, user_id, sales_amount
          FROM online_sale
          WHERE sales_date>=TO_DATE('20220301','YYYYMMDD') AND sales_date<TO_DATE('20220401','YYYYMMDD')
          UNION ALL
          SELECT TO_CHAR(sales_date,'YYYY-MM-DD') AS sales_date, product_id, NULL AS user_id, sales_amount
          FROM offline_sale
          WHERE sales_date>=TO_DATE('20220301','YYYYMMDD') AND sales_date<TO_DATE('20220401','YYYYMMDD')
      )
      ORDER BY sales_date, product_id, user_id;

SQL 내장함수

문자 함수

UPPER, LOWER, INITCAP

  • 대·소문자를 바꿔주는 함수. 링크
    • UPPER: 대문자로 변환

    • LOWER: 소문자로 변환

    • INITCAP: 첫글자는 대문자, 나머지는 소문자

      SELECT animal_id, name
      FROM animal_ins
      WHERE UPPER(name) LIKE '%EL%'
      AND animal_type = 'Dog'
      ORDER BY name;

LENGTH

  • 특정 문자열의 길이를 구할때 사용

SUBSTR

  • 문자열 중 일부를 추출할 때 사용하는 함수
  • SUBSTR(문자열 데이터, 시작 위치[, 추출 길이]) 1번부터 시작 링크
    SELECT SUBSTR(PRODUCT_CODE,1,2) AS category, COUNT(*)
    FROM PRODUCT 
    GROUP BY SUBSTR(PRODUCT_CODE,1,2)
    ORDER BY category;

INSTR

  • 문자열 데이터 안에 특정 문자나 문자열이 어디에 포함되어 있는 알고자 할 때
  • INSTR(대상 문자열 데이터, 위치를 찾으려는 부분 문자[, 시작위치, 몇 번째 나온것 반환])
  • 문자의 위치를 반환하는 함수로 SUBSTR와 함께 쓰기 좋다. 링크
    SELECT history_id, MIN(daily_fee*(1-NVL(DISCOUNT_RATE,0)/100)*(end_date-start_date+1)) AS fee
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY ccrh 
        LEFT JOIN CAR_RENTAL_COMPANY_CAR ccc
            ON ccrh.car_id = ccc.car_id 
        LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN crcdp
            ON (ccc.car_type = crcdp.car_type 
                AND (end_date-start_date+1) >= TO_NUMBER(SUBSTR(duration_type,1,INSTR(duration_type,'일')-1)))
    WHERE ccc.car_type = '트럭'
    GROUP BY history_id
    ORDER BY fee DESC, history_id DESC;

REPLACE

  • 특정 문자열 데이터에 포함된 문자를 다른 문자로 대체
  • REPLACE(문자열 데이터 또는 열 이름, 찾는 문자, 대체할 문자)

CONCAT

  • 두 개의 문자열 데이터를 하나의 데이터로 연결해 주는 역할
  • CONCAT(문자열 데이터 또는 열 이름,문자열 데이터 또는 열 이름)
  • 문자열 데이터 또는 열 이름||문자열 데이터 또는 열 이름 ||를 사용해도 동일한 효과

숫자 함수

ROUND

  • 특정 위치에서 반올림 ROUND(숫자,반올림위치) 링크
    SELECT car_id, ROUND(AVG(end_date-start_date+1),1) AS average_duration
    FROM car_rental_company_rental_history
    GROUP BY car_id
    HAVING ROUND(AVG(end_date-start_date+1),1) >= 7
    ORDER BY average_duration DESC, car_id DESC;

TRUNC

  • 특정 위치에서 버림 TRUNC(숫자,버림위치) 링크
    SELECT TRUNC(price,-4) AS price_group, COUNT(*) AS products
    FROM product
    GROUP BY TRUNC(price,-4)
    ORDER BY price_group;

CEIL

  • CEIL(숫자): 지정 숫자 보다 큰 정수 중 가장 작은 정수

FLOOR

  • FLOOR(숫자):지정 숫자 보다 작은 정수 중 가장 큰 정수

MOD

  • MOD(나눗셈 될 숫자, 나눌 숫자): 지정된 숫자를 나눈 나머지

날짜 함수

연산

  • 날짜 데이터 + 숫자: 날짜 데이터보다 숫자만큼 일수 이후의 날짜
  • 날짜 데이터 - 숫자: 날짜 데이터보다 숫자만큼 일수 이전의 날짜
  • 날짜 데이터 - 날짜 데이터: 두 날짜 데이터 간의 일수 차이 링크
    • 일수 차이기 때문에 일일당 요금 등을 구하는 곳에서는 1일 만큼을 더할 필요가 있음

      SELECT animal_id, name
      FROM(
          SELECT ao.animal_id, ao.name, (ao.datetime-ai.datetime) AS time
          FROM animal_outs ao LEFT JOIN animal_ins ai
          ON ao.animal_id = ai.animal_id
          WHERE ai.animal_id IS NOT NULL
          ORDER BY time DESC
      )
      WHERE ROWNUM<3;
  • 날짜 데이터 + 날짜 데이터: 연산 불가

형 변환 함수

  • 대부분 날짜 데이터관련 형변환으로 출력형식, 비교방법을 알면 충분하다.
  • 문제와 무관하지만, date의 경우 인덱스를 타는 경우가 많다고 하니, 문자로 만들어 비교하는 것 보다, 날짜데이터를 만들어서 비교하는 것이 유리한 것 같다.

TO_CHAR

  • 날짜, 숫자 데이터를 문자 데이터로 변환해주는 함수
  • TO_CHAR(datetime, 'YYYY-DD-MM')꼴로 원하는 출력 형태로 만들 수 있다. 링크
    SELECT animal_id, name, TO_CHAR(datetime,'YYYY-MM-DD')
    FROM animal_ins
    ORDER BY animal_id;
  • WHERE 조건에서도 사용 가능하다. 링크
    SELECT DISTINCT(ccc.car_id)
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY ccrh 
        LEFT JOIN CAR_RENTAL_COMPANY_CAR ccc
        ON ccrh.CAR_ID = ccc.CAR_ID
    WHERE ccc.car_type = '세단' AND TO_CHAR(ccrh.start_date,'MM')=10
    ORDER BY car_id DESC;

TO_NUMBER

  • 문자 데이터를 숫자 데이터로 변환해주는 함수 링크
  • 문자로 바꾼 date는 문자이기 때문에 9시가 09시로 출력되기 때문에 오답이 되는 경우가 있어 이를 숫자로 바꾸기 위해 TO_NUMBER로 감싼다.
    SELECT TO_NUMBER(TO_CHAR(datetime,'HH24')) AS hour, COUNT(*)
    FROM animal_outs
    WHERE TO_NUMBER(TO_CHAR(datetime,'HH24'))>8
        AND TO_NUMBER(TO_CHAR(datetime,'HH24'))<20
    GROUP BY TO_NUMBER(TO_CHAR(datetime,'HH24'))
    ORDER BY hour;

TO_DATE

  • 문자 데이터를 날짜 데이터로 변환하는 함수 링크
  • 사실 TO_CHAR를 사용해도 결과는 같지만, 문자열 비교보다 DATE 비교가 통상 빠르다고 해서 사용했다.
    SELECT *
    FROM(
        SELECT crcc.car_id, crcc.car_type, crcc.daily_fee*(1-crcdp.discount_rate/100)*30 AS fee
        FROM CAR_RENTAL_COMPANY_CAR crcc 
            LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN crcdp
            ON crcc.car_type=crcdp.car_type 
                AND crcdp.duration_type='30일 이상'
        WHERE (
            crcc.car_type IN('SUV','세단')
            AND crcc.car_id IN(
                SELECT car_id
                FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
                GROUP BY car_id
                HAVING MAX(
                    CASE WHEN (TO_DATE('2022-11-01','YYYY-MM-DD') BETWEEN start_date AND end_date) THEN 1
                    WHEN (TO_DATE('2022-11-30','YYYY-MM-DD') BETWEEN start_date AND end_date) THEN 1 
                    ELSE 0 END
                )=0
            ) 
       )
    )
    WHERE fee>=500000 AND fee<2000000
    ORDER BY fee DESC, car_type ASC, car_id DESC;

NULL 처리 함수

  • **NULL을 처리하기 위해 값이 없는 경우를 처리할 때 사용하는 함수**

NVL

  • 열 또는 데이터가 NULL이 아닐 경우 데이터를 그대로 반환, NULL인경우 지정 데이터 반환
  • NVL(NULL인지 여부를 검사할 데이터 또는 열, 앞의 데이터가 NULL일 경우 반환할 데이터) 링크
SELECT warehouse_id, warehouse_name, address, NVL(freezer_yn,'N')
FROM food_warehouse
WHERE address LIKE '경기도 %'
ORDER BY warehouse_id;

NVL2

  • NVL함수와 비슷하지만 데이터가 NULL이 아닐 때 반환할 데이터를 추가로 지정
  • NVL(NULL인지 여부를 검사할 데이터 또는 열, 앞의 데이터가 NULL일 경우 반환할 데이터 또는 계산식, 앞의 데이터가 NULL일 경우 반환할 데이터 또는 계산식)

SQL 다중행 함수

  • 여러 행을 바탕으로 하나의 결과 값을 도출해 내기 위해 사용하는 함수
  • SUM, COUNT, MAX, MIN, AVG
  • DISTINCT, ALL 키워드를 사용할 수 있다.
    • 중복데이터의 제거 가능

SUM

  • 지정한 데이터의 합 반환 링크
    SELECT category, SUM(sales) AS total_sales
    FROM  book_sales bs 
        LEFT JOIN book b
        ON bs.book_id = b.book_id
    WHERE TO_CHAR(sales_date,'YYYY-MM') = '2022-01'
    GROUP BY category
    ORDER BY category

COUNT

  • 지정한 데이터의 개수 반환
  • COUNT(*)꼴로 많이 사용하지만 COUNT(컬럼명)형태로도 사용한다.
  • GROUP BY 없이 단독으로 사용하면, 레코드의 수를 계산해준다. 링크
    SELECT COUNT(*)
    FROM animal_ins;
  • GROUP BY 사용시 그 그룹에 해당하는 레코드의 수를 계산한다. 링크
    SELECT name, COUNT(*) AS count
    FROM ANIMAL_INS 
    WHERE name IS NOT NULL
    GROUP BY name
    HAVING COUNT(name)>1
    ORDER BY name;

MAX

  • 지정한 데이터 중 최대값 반환 링크
    SELECT MAX(price) AS MAX_PRICE
    FROM PRODUCT;
  • 최대 값을 갖는 행의 정보 가져오기→ 서브쿼리 링크
    SELECT product_id, product_name, product_cd, category, price
    FROM food_product
    WHERE price = (SELECT MAX(price) FROM food_product);

MIN

  • 지정한 데이터 중 최소값 반환 링크
    SELECT MIN(datetime) AS 시간
    FROM animal_ins;

AVG

  • 지정한 데이터의 평균값 반환 링크
    SELECT round(avg(daily_fee)) AS AVERAGE_FEE 
    FROM car_rental_company_car
    WHERE car_type = 'SUV';

기타

오라클 계층쿼리 LEVEL

  • CONNECT BY LEVEL쿼리는 계층형 쿼리로 오라클에서 값을 연속적으로 증가하는 값이 필요로 할 때 사용
    SELECT LEVEL
    FROM DUAL
    CONNECT BY LEVEL < 4;
    // 1
    // 2
    // 3
  • 문제를 풀면서 다른 사람의 풀이를 통해서 학습할 수 있었다. 링크
    SELECT hour, sum(count) AS count
    FROM(
        SELECT TO_NUMBER(TO_CHAR(datetime,'hh24')) AS hour, COUNT(*) AS count
        FROM animal_outs
        GROUP BY TO_NUMBER(TO_CHAR(datetime,'hh24'))
        UNION 
        SELECT LEVEL - 1 AS HOUR, 0 AS count
        FROM DUAL
        CONNECT BY LEVEL < 25 
    )
    GROUP BY hour
    ORDER BY hour;

마치며

  • 항상 더 좋은 방법이 있을 것이고, 지금 만든 로직이 엉망일 수도 있다.
  • 그래도 하나하나 시도하는 것이 중요한 것 아닐까?
  • 내가 잘못된 , 비효율적인 방향으로 가고 있을 때, 주변에서 '그거 그렇게 하는거 아닌데...' 하고 말해주는 곳에 있고 싶다.

참고자료

  • ‘오라클로 배우는 데이터베이스 입문’(2018) 이지스 퍼블리싱

0개의 댓글