Algorithm/programmers.co.kr

프로그래머스 SQL 고득점 kit

winney916 2022. 2. 20. 01:36
728x90

1. SELECT 부분

 - ORDER BY 옵션에는 ASCDESC가 있다. 내림차순이 4글자인걸 기억하자.

 

 - WHERE 사용법

    - WHERE column = 'data'   : 동일할 때

    - WHERE column != 'data'  : 다를 때

    - WHERE column is NULL  : NULL값일 때

    - WHERE column is not NULL  : NULL이 아닐 때

 

 

2. SUM, MAX, MIN 부분

 - 갯수 세기

    - SELECT COUNT(*) FROM DATE_TABLE; : 이렇게 세고자 하는 대상에 COUNT()를 사용해주면 된다.

    - SELECT COUNT( DISTINCT * ) FROM DATA_TABLE; : 이렇게 하면 유일값 기준으로 갯수를 세준다.

 

3. GROUP BY 부분

- 조건부 그룹

  - 보통 조건을 넣어줄 때 WHERE를 사용했지만 GROUP BY 부분에서는 다르다.

  - GROUP BY column HAVING condition;  : HAVING 절로 조건을 달 수 있다.

  * SQL에서 조건을 사용할 때

    : 파이썬처럼 0<=X<20 하면 안된다.

        -> 0 <= X AND X < 20 이렇게 작성하길.

 

  - DATETIME 활용법

    - DATETIME 데이터에 YEAR, MONTH, DAY, HOUR, MINUTE, SECOND 를 함수로 적용하면 해당 값을 얻을 수 있다.

 

- SET 활용 [ 입양 시각 구하기 (2) ]

  : SQL에서 변수를 활용해보자.

SET @HOUR = -1;
SELECT (@HOUR := @HOUR + 1) AS HOUR
FROM ANIMAL_OUTS;

 1. HOUR 라는 변수를 생성하고

 2. ANIMAL_OUTS의 ROW 갯수만큼 HOUR 컬럼을 생성하는데, 컬럼의 ROW값에 1씩 더해가는 형태이다.

결과적으로 이렇게 0~99까지 (ANIMAL_OUTS의 열 갯수가 100개이다.)

HOUR라는 컬럼에 ROW가 생성된다.

 

이제 이걸 문제풀이에 활용해보자.

 

SELECT ... FROM ... 의 특징은

FROM 뒤에 있는 데이터에 기반하여

SELECT 뒤에 있는 column에 기반한

데이터 테이블을 생성한다고 생각하면 좋다.

 

 - 서브쿼리 (Subquery)

  : 하나의 SQL문 안에 포함되어 있는 또 다른 SQL문.

SELECT *
FROM db_table
WHERE table_fk IN (
    #서브쿼리
    SELECT table_fk FROM db_table_other WHERE ..
    )

 이제 위 두가지 개념을 합하여 문제를 해결해보자.

SET @HOUR = -1;
SELECT
    (@HOUR := @HOUR + 1) AS HOUR,
    (SELECT COUNT(*)
    FROM ANIMAL_OUTS
    WHERE @HOUR = HOUR(DATETIME)) AS COUNT
FROM ANIMAL_OUTS
    WHERE @HOUR < 23;

두개의 컬럼을 만든다.

하나는 HOUR 변수

하나는 서브쿼리

 

@HOUR := @HOUR +1 은 PYTHON에서 HOUR += 1 과 같은 의미라고 생각하면 된다.

컬럼 하나를 생성할 때마다 1 씩 더해진다.

그리고 이와 동일한 수(시간)을 가진 ROW만 기존 테이블에서 COUNT한 뒤 두번째 컬럼으로 넣어준다.

문제에서 22시까지 요구했기에 WHERE로 제한해준다.

 

이런 식으로 진행된 풀이이다. 여태 풀었던 문제 중에 가장 어려웠다.

 

4. IS NULL 부분

 - IS NULL : NULL은 다른 값들과 다르다. NULL == NULL 은 False이다. 즉 다른 값들 처럼 연산하면 안된다.

                때문에 별도의 연산기능이 있는데 그게 IS NULL 이다. NULL 여부를 판단할 대 사용하면 된다.

 

 - IS NOT NULL : 부정형은 이렇게 쓴다.

 

 - IFNULL(column, 'data') : column을 불러올 때 null값을 대체하고 싶다면 이렇게 진행하면 된다. 이건 sql 클라이언트마다 차이가 좀 있다. (ISNULL, NVL 등..) 내가 사용하는 MYSQL에서는 IFNULL이다! 개인적으로 이게 더 직관적이라고 생각한다.

 

5. JOIN 부분

 - 대부분의 연산은 LEFT JOIN으로 진행된다고 했다. (생활코딩)

 자, 다음과같은 데이터를 얻고싶다면 어떻게 해야할까?

A, B를 LEFT JOIN한 후에 교집합 부분을 제외하면 된다.

 

교집합 부분에는 A테이블에 존재하는 컬럼에 NULL이 대응하기때문에 그 NULL을 기준으로 정리하면 된다.

 

 

 - SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id

   WHERE (null인 A테이블의 컬럼 중 하나) IS NULL;

 

 - DATETIME 데이터도 =, >, <  등의 연산이 가능하다.

 

 - LEFT(data, stop) : 문자열 슬라이싱 방법이다.

 - LEFT(data, start, stop) : 이렇게도 가능하다.

물론 RIGHT도 가능하다.

 

 - SUBSTRING_INDEX(data, delimiter, counter) : 이 형태는, delimiter가 counter번째 나올 때까지 끊어준다. 이는 인덱스처럼 동작하기 때문에 -1, -2도 입력 가능하다.

 

6. STRING, DATE 부분

 - IN (list) : WHERE 절에서 여러개의 값과 비교하고 싶을 때 사용하면 좋다.

EX) WHERE column IN (data1, data2, data3) 

 

 - LOCATE("string", column) : colimn에 string이 존재하는지 여부를 판단할 때 사용하면 좋다.

 

 - IF(condition, value_if_true, value_if_false) : 조건에 따른 값을 입력하고 싶을 때 사용한다. SQL판 IF문.

 

 - LEFT(DATE(INS.DATETIME), 10) AS "날짜" : datatime 데이터에서 년, 월, 일을 추출하라는 문제에서 내가 했던 방법이다. 답은 맞았지만 완전히 틀렸다 ㅋㅋㅋ

  : datetime 데이터에는 DATE_FORMAT이라는 함수를 사용할 수 있는데, 인자로 datetime데이터와 형식을 받는다.

 

다음이 형식 연산자이다.

%a Abbreviated weekday name (Sun to Sat)
%b Abbreviated month name (Jan to Dec)
%c Numeric month name (0 to 12)
%D Day of the month as a numeric value, followed by suffix (1st, 2nd, 3rd, ...)
%d Day of the month as a numeric value (01 to 31)
%e Day of the month as a numeric value (0 to 31)
%f Microseconds (000000 to 999999)
%H Hour (00 to 23)
%h Hour (00 to 12)
%I Hour (00 to 12)
%i Minutes (00 to 59)
%j Day of the year (001 to 366)
%k Hour (0 to 23)
%l Hour (1 to 12)
%M Month name in full (January to December)
%m Month name as a numeric value (00 to 12)
%p AM or PM
%r Time in 12 hour AM or PM format (hh:mm:ss AM/PM)
%S Seconds (00 to 59)
%s Seconds (00 to 59)
%T Time in 24 hour format (hh:mm:ss)
%U Week where Sunday is the first day of the week (00 to 53)
%u Week where Monday is the first day of the week (00 to 53)
%V Week where Sunday is the first day of the week (01 to 53). Used with %X
%v Week where Monday is the first day of the week (01 to 53). Used with %x
%W Weekday name in full (Sunday to Saturday)
%w Day of the week where Sunday=0 and Saturday=6
%X Year for the week where Sunday is the first day of the week. Used with %V
%x Year for the week where Monday is the first day of the week. Used with %v
%Y Year as a numeric, 4-digit value
%y Year as a numeric, 2-digit value

2022-02-23의 형태로 출력하고 싶다면

DATE_FORMAT(DATETIME, '%Y-%m-%d') 하면 된다.