본문 바로가기
알고리즘/프로그래머스

[SQL] 문법 정리

by sum_mit45 2022. 3. 16.
728x90
반응형

SELECT문

SELECT select_list [ INTO new_table ]  
[ FROM table_source ] [ WHERE search_condition ]  
[ GROUP BY group_by_expression ]  
[ HAVING search_condition ]  
[ ORDER BY order_expression [ ASC | DESC ] ]
  • INTO : 조건에 맞는 기존 테이블의 열 내용을 새 테이블로 가져와 테이블을 만드는 것
  • GROUP BY : 그룹 
  • ORDER BY : 정렬
  • HAVING: 특정 컬럼을 그룹화한 결과에 조건을 걸 때 사용
  • WHERE는 그룹화 하기 전, HAVING은 그룹화 한 후에 조건

 

프로그래머스 예제

1. 모든 동물의 정보를 ANIMAL_ID 순으로 조회

SELECT * FROM ANIMAL_INS ORDER BY ANIMAL_ID ASC;
SELECT NAME,DATETIME FROM ANIMAL_INS ORDER BY ANIMAL_ID DESC;
SELECT ANIMAL_ID,NAME FROM ANIMAL_INS ORDER BY ANIMAL_ID ASC;
SELECT ANIMAL_ID,NAME,DATETIME FROM ANIMAL_INS ORDER BY NAME ASC, DATETIME DESC;

2. 특정 조건을 만족하는 동물의 특정 열의 정보를 조회

SELECT ANIMAL_ID, NAME FROM ANIMAL_INS WHERE INTAKE_CONDITION = 'Sick';
SELECT ANIMAL_ID, NAME FROM ANIMAL_INS WHERE INTAKE_CONDITION != 'Aged';

3. 특정 열에 대한 상위 n개의 동물의 특정 열의 정보를 조회

SELECT NAME FROM ANIMAL_INS ORDER BY DATETIME ASC LIMIT 1;
SELECT DATETIME FROM ANIMAL_INS ORDER BY DATETIME DESC LIMIT 0,1;
SELECT DATETIME FROM ANIMAL_INS ORDER BY DATETIME ASC LIMIT 0,1;

 

 

집계함수

COUNT: 원하는 데이터의 갯수 추출

테이블 전체의 행 숫자를 알고 싶다면 COUNT(*)

특정 열의 숫자를 확인하려면 COUNT(열)

 

1) NULL 값이 포함되면 count하지 않는다.

2) 중복값은 포함해서 집계한다. -> 중복값을 제외하고 count하기 위해서는 DISTINCT 사용

COUNT(DISTINCT 열)

 

SUM

 

AVG

 

MIN

 

MAX

 

프로그래머스 예제

SELECT MAX(DATETIME) FROM ANIMAL_INS;
SELECT DATETIME FROM ANIMAL_INS ORDER by DATETIME DESC Limit 1;

SELECT MIN(DATETIME) FROM ANIMAL_INS;
SELECT DATETIME FROM ANIMAL_INS ORDER BY DATETIME ASC LIMIT 0,1;

SELECT COUNT(* FROM ANIMAL_INS ;
SELECT COUNT(DISTINCT NAME) FROM ANIMAL_INS ;

 

GROUP BY

- 구하려는 값이 전체 행의 갯수가 아닌 그룹별로 집계하려고 할 때 사용

- 그룹으로 묶는 컬럼이 아닌 다른 컬럼은 SELECT 문에 포함되면 안된다.

 

SELECT 컬럼 FROM 테이블 GROUP BY 그룹화할 컬럼 HAVING 조건식

 

프로그래머스 예제

1. 고양이와 개가 각각 몇 마리인지 조회

SELECT ANIMAL_TYPE, COUNT(ANIMAL_TYPE) FROM ANIMAL_INS
GROUP BY ANIMAL_TYPE
ORDER BY ANIMAL_TYPE ASC;

2. 동물 이름 중 두번 이상 쓰인 이름과 해당 이름이 쓰인 횟수, 이름은 순으로 조회

SELECT NAME, COUNT(*) AS 'COUNT'
FROM ANIMAL_INS 
WHERE NAME IS NOT NULL
GROUP BY NAME
HAVING COUNT('COUNT') > 1
ORDER BY NAME ASC;

 

3. 각 시간대별로 입양이 몇 건 발생 했는지 시간대순으로 정렬

 

SELECT HOUR(DATETIME) AS 'HOUR', COUNT(HOUR(DATETIME)) AS 'COUNT' FROM ANIMAL_OUTS
GROUP BY HOUR
HAVING HOUR >=9 AND HOUR < 20
ORDER BY HOUR ASC;

 

4. 각 시간대 별로 입양이 발생한 건수를 시간대순으로 정렬

- 재귀문 사용해서 NULL 값들도 표현

WITH RECURSIVE cte AS (
    SELECT 0 AS HOUR 
    UNION ALL
    SELECT HOUR+1 FROM cte
    WHERE HOUR < 23
)

SELECT HOUR, COUNT(HOUR(DATETIME)) as 'COUNT' from cte
LEFT OUTER JOIN (ANIMAL_OUTS)
ON HOUR(DATETIME) = HOUR
GROUP BY HOUR
ORDER BY HOUR

 

JOIN 

- JOIN은 데이터베이스 내의 여러 테이블에서 가져온 레코드를 조합하여 하나의 테이블이나 결과 집합으로 표현해준다.

 

1. INNER JOIN

- INNER JOIN은 ON 절과 함께 사용되며, ON 절의 조건을 만족하는 데이터만을 가져온다.

- ON절에서는 WHERE 절에서 사용할 수 있는 모든 조건을 사용할 수 있다.

- A와 B의 교집합

 

2. LEFT JOIN 

- LEFT JOIN은 첫번째 테이블을 기준으로 두번째 테이블을 조합하는 JOIN

- ON 절의 조건을 만족하지 않는 경우에는 첫 번째 테이블의 필드 값을 그대로 가져온다. 하지만 해당 레코드의 두번째 테이블의 필드 값은 모두 NULL로 표시된다.

 

3. RIGHT JOIN

- RIGHT JOIN은 두번째 테이블을 기준으로 첫번째 테이블을 조합하는 JOIN

- ON 절의 조건을 만족하지 않는 경우에는 두번째 테이블의 필드 값을 그대로 가져온다. 하지만 해당 레코드의 첫번째 테이블의 필드 값은 모두 NULL로 표시된다.

 

프로그래머스 예제

1. 

SELECT ANIMAL_OUTS.ANIMAL_ID,ANIMAL_OUTS.NAME FROM ANIMAL_OUTS
LEFT JOIN ANIMAL_INS ON
ANIMAL_OUTS.ANIMAL_ID = ANIMAL_INS.ANIMAL_ID
WHERE ANIMAL_INS.ANIMAL_ID IS NULL
ORDER BY ANIMAL_ID

- 테이블명.컬럼값 으로 접근 가능

 

2. 

-- 코드를 입력하세요
SELECT ANIMAL_OUTS.ANIMAL_ID, ANIMAL_OUTS.NAME FROM ANIMAL_OUTS
LEFT JOIN ANIMAL_INS ON
ANIMAL_OUTS.ANIMAL_ID = ANIMAL_INS.ANIMAL_ID
WHERE ANIMAL_INS.DATETIME > ANIMAL_OUTS.DATETIME
ORDER BY ANIMAL_INS.DATETIME ASC;

- 처음에 LEFT JOIN ANIMAL_OUTS ON 으로 작성하였더니

Not unique table/alias: 'ANIMAL_OUTS' 이런 오류가 나왔다.

SELECT (열) FROM (첫번째 Table) LEFT JOIN (두번째 Table)

 

3. 아직 입양을 못 간 동물 중 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호 시작일 조회

- 들어온 동물의 정보를 담은 테이블(INS) 기준에서 입양보낸 동물의 정보를 빼면(OUTS) 입양 못 간 동물들이 나온다.

- 이 중 DATETIME이 가장 낮은(오래전부터 있던) 동물 3마리 조회

SELECT ANIMAL_INS.NAME, ANIMAL_INS.DATETIME FROM ANIMAL_INS
LEFT JOIN ANIMAL_OUTS ON
ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.DATETIME IS NULL
ORDER BY ANIMAL_INS.DATETIME ASC LIMIT 3

 

4. 보호소에 들어올 당시에는 중성화 되지 않았지만, 보호소를 나갈 당시에 중성화된 동물의 아이디와 생물 종, 이름을 아이디 순으로 조회

- SEX_UPON_INTAKE에서는 Intact이라는 말이 들어가 있지만, SEX_UPON_OUTCOME에는 Intact라는 말이 없다

(중성화되면 Neutered Male, Spayed Female로 표현되어 있음)

SELECT ANIMAL_INS.ANIMAL_ID, ANIMAL_INS.ANIMAL_TYPE, ANIMAL_INS.NAME FROM ANIMAL_INS
LEFT JOIN ANIMAL_OUTS ON
ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_INS.SEX_UPON_INTAKE LIKE 'Intact%' AND
ANIMAL_OUTS.SEX_UPON_OUTCOME NOT LIKE 'Intact%'
ORDER BY ANIMAL_INS.ANIMAL_ID ASC;

 

WHERE

 

WHERE 조건1 AND 조건2

 

WHERE 조건1 OR 조건2

 

WHERE NOT 조건

 

WHERE 컬럼명 LIKE '특정문자열' 

- LIKE, NOT LIKE

- '%' : 임의의 문자 또는 문자열, 빈 문자열 

   %VALUE : VALUE로 끝나는 값, VALUE% : VALUE로 시작하는 값, %VALUE% : VALUE가 들어가는 값

- '_' : 임의의 문자 한 개

 

String, Date

 

CASE문

-형식

CASE 컬럼

    WHEN 조건1 THEN 값1

    WHEN 조건2 THEN 값2

    ELSE 값3

END

 

-사용

 약어나 코드를 읽기 쉬운 값으로 바꿔줄 때

 데이터를 범주화 할 때

프로그래머스 예제

1. 동물보호소에 들어온 동물 중 이름이 XXX인 동물의 아이디와 이름, 성별 및 중성화 여부를 조회

SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE FROM ANIMAL_INS
WHERE NAME LIKE 'Lucy' OR
NAME LIKE 'Ella' OR
NAME LIKE 'Pickle' OR
NAME LIKE 'Rogan' OR
NAME LIKE 'Sabrina' OR
NAME LIKE 'Mitty'


SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
where name in ('Lucy', 'Ella', 'Pickle', 'Rogan', 'Sabrina', 'Mitty');

 

2. 이름이 el이 들어가는 개의 아이디와 이름을 조회

SELECT ANIMAL_ID,NAME FROM ANIMAL_INS
WHERE NAME LIKE '%el%' AND ANIMAL_TYPE LIKE 'Dog'
ORDER BY NAME ASC;

- ANIMAL_TYPE = 'dog' 로 해도 됨.

 

3. 동물의 아이디와 이름, 중성화 여부를 아이디 순으로 조회

- 중성화 되어있다면 'O', 아니면 'X'

SELECT ANIMAL_ID, NAME,
CASE 
    WHEN SEX_UPON_INTAKE LIKE 'Intact%' THEN 'X'
    ELSE 'O'
END AS '중성화'
FROM ANIMAL_INS
ORDER BY ANIMAL_ID

 

4. 입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디와 이름을 보호 기간이 긴 순으로 조회

- ORDER BY 하고 보호기간 순 적기

SELECT ANIMAL_OUTS.ANIMAL_ID, ANIMAL_OUTS.NAME FROM ANIMAL_OUTS
INNER JOIN ANIMAL_INS 
ON ANIMAL_OUTS.ANIMAL_ID = ANIMAL_INS.ANIMAL_ID
ORDER BY ANIMAL_OUTS.DATETIME - ANIMAL_INS.DATETIME DESC LIMIT 2;

 

5. DATETIME->DATE 형 변환

SELECT ANIMAL_ID, NAME, DATE_FORMAT(DATETIME, '%Y-%m-%d') FROM ANIMAL_INS
ORDER BY ANIMAL_ID;

 

기타

IFNULL(NAME, 'No name') // 만약 NAME값이 NULL이라면, No name으로 설정하기

728x90
반응형