SQL 준비
WHERE
비교 연산자
= , < , > , <= ex) where col = 10
문자형과 비교시에는 WHERE CITY = 'Paris'와 같이 인용부호로 감싸주어야 함.
부정 비교 연산자
!=, not 컬럼명 = ex) where col ≠ 10 , where not col = 10
SQL 연산자
BETWEEN A AND B : A와 B의 사이 where col between 1 and 10
LIKE '비교 문자열'
비교 문자열을 포함
%는 문자열을 의미, '_'는 하나의 문자를 의미
ex) where col like '방탄%'
IN (리스트)
LIST 중 하나와 일치
where col in (1,3,5)
IS NULL
where col is null
부정 SQL 연산자
NOT BETWEEN A AND B
A와 B의 사이가 아님
where col not between 1 and 10
NOT IN (LIST)
where col ot in (1,3,5)
IS NOT NULL
NULL 값이 아님
where col is not null
논리 연산자
AND
모든 조건이 TRUE여야 함
where col > 1 and col < 10
OR
하나 이상의 조건이 TRUE여야 함
where col = 1 or col = 10
NOT
TRUE면 FALSE이고 FALSE이면 TRUE
GROUP BY, HAVING 절
데이터를 GROUP BY를 통해 그룹별로 묶고
집계 함수를 통해 그룹별로 집계 데이터를 도출할 수 있다.
COUNT(*) : 전체 ROW를 Count 하여 반환
COUNT(컬럼) : 컬럼값이 Null인 Row를 제외하고 Count하여 반환
COUNT(DISTINCT 컬럼) : 컬럼값이 Null이 아닌 Row에서 중복을 제거한 Count를 반환
SUM(컬럼) : 컬럼값들의 합계를 반환
AVG(컬럼) : 컬럼값들의 평균을 반환 , NULL인 데이터를 제외한 컬럼값들의 평균을 반환
MIN(컬럼) : 컬럼값들의 최솟값을 반환
MAX(컬럼) : 컬럼값들의 최댓값을 반환
근데 집계 함수가 꼭 GROUP BY와 함께 쓰는 건 아니다.
GROUP BY 없이 사용할 때 : 전체에 대한 계산 SELECT AVG(TOTAL_AMOUNT) FROM ORDERS
GROUP BY를 사용할 때, SELECT 절에는 다음 두 종류의 것만 올 수 있습니다.
GROUP BY절에 사용된 컬럼 (예: INGREDIENT_TYPE)집계 함수(Aggregate Function) (예: SUM(TOTAL_ORDER), COUNT(FLAVOR))
HAVING
HAVING 절은 GROUP BY 절을 사용할 때 WHERE 절처럼 사용하는 조건절
SELECT - 5
FROM - 1
WHERE - 2 -> 먼저 필터링
GROUP BY - 3
HAVING - 4 그룹화된 결과에 대해 조건 적용
ORDER BY - 6 최종 결과를 정렬
2021년 7월 한 달 동안의 판매 데이터를 상품 코드로 그룹핑해서 COUNT를 구하면 상품별 판매량이 나오는데 HAVING 절을 이용하면 한 달간 1000개 이상 팔린 상품만 출력할 수 있다.
SELECT PRODUCT_CODE, COUNT(ORDER_CNT) AS ORDER_CNT
FROM ORDER_PRODUCT
WHERE ORDER_DATE BETWEEN '20210701' AND '20210731'
GROUP BY PRODUCT_CODE
HAVING COUNT(ORDER_CNT) ≥ 1000;
JOIN
EQUI JOIN , EQUAL 조건으로
NON EQUI JOIN
STANDARD JOIN
Inner Join
SELECT A.컬럼1, A.컬럼2, B.컬럼1 FROM PRODUCT A INNER JOIN PRODUCT_REVIEW B ON A.PRODUCT_CODE = B.PRODUCT_CODE
OUTER JOIN
left outer join
SELECT A.컬럼1, A.컬럼2, B.컬럼1 FROM PRODUCT A LEFT OUTER JOIN PRODUCT_REVIEW B ON A.PRODUCT_CODE = B.PRODUCT_CODE
right outer join
full outer join
왼쪽, 오른쪽 테이블 모두 출력되는 방식
서브 쿼리
SELECT 절 : 스칼라 서브쿼리 FROM 절 : 인라인 뷰 WHERE 절, HAVING 절 : 중첩 서브쿼리
스칼라 서브 쿼리 : 컬럼 대신 사용되므로 반드시 하나의 값만을 반환해야 한다.
인라인 뷰 : FROM 절 등 테이블명이 올 수 있는 위치에 사용 가능하다.
중첩 서브 쿼리
WHERE 절과 HAVING 절에 사용할 수 있다.
비연관 서브 쿼리 : 메인쿼리와 관계를 맺고 있지 않음
SELECT NAME, JOB, BIRTHDAY, AGENCY_CODE FROM ENTERTAINER WHERE AGENCY_CODE = ( SELECT AGENCY_CODE FROM AGENCY WHERE AGENCY_NAME 'EDAM엔터테인먼트');
연관 서브 쿼리 : 메인쿼리와 관계를 맺고 있음
음료별 가장 많은 주문수량을 가진 주문번호를 조회한다.
SELECT ORDER_NO, DRINK_CODE, ORDER_CNT FROM CAFE_ORDER A WHERE ORDER_CNT = (SELECT MAX(ORDER_CNT) FROM CAFE_ORDER B
집합 연산자
UNION ALL : 각 쿼리의 결과 집합의 합집합이다. 중복된 행도 그대로 출력됨
SELECT * FROM RUNNING_MAN UNION ALL SELECT * FROM INFINITE_CHALLENGE;
UNION : 각 쿼리의 결과 집합의 합집합. 중복된 행은 한 줄로 출력
SELECT * FROM RUNNING_MAN UNION SELECT * FROM INFINITE_CHALLENGE;
INTERSECT : 각 쿼리의 결과 집합의 교집합이다. 중복된 행은 한 줄로 출력됨
SELECT * FROM RUNNING_MAN INTERSECT SELECT * FROM INFINITE_CHALLENGE;
MINUS/EXCEPT : 앞에 있는 쿼리의 결과 집합에서 뒤에 있는 쿼리의 결과 집합을 뺀 차집합이다. 중복된 행은 한 줄로 출력된다.
SELECT * FROM RUNNING_MAN MINUS SELECT * FROM INFINITE_CHALLENGE;
OVER()는 "윈도우 함수(Window Functions)"를 정의하는 데 사용되는 핵심 구문입니다. 윈도우 함수는 GROUP BY처럼 행을 하나로 집계하여 축소하지 않고, 각 행은 그대로 유지하면서 특정 범위(윈도우)의 행들을 기준으로 계산한 값을 각 행에 추가해주는 함수입니다.
OVER()와 함께 사용되는 함수는 크게 세 가지 그룹으로 나눌 수 있습니다.
집계 함수 (Aggregate Functions)
SUM()이 여기에 속합니다. GROUP BY와 함께 쓰이는 대부분의 집계 함수를 OVER()와 함께 사용할 수 있습니다.
SUM(): 파티션(그룹) 내의 합계 또는 누적 합계
COUNT(): 파티션 내의 개수 또는 누적 개수
AVG(): 파티션 내의 평균 또는 누적 평균
MAX() / MIN(): 파티션 내의 최댓값/최솟값
예시: 각 직원의 급여와 함께, 해당 직원이 속한 부서의 전체 급여 합계를 함께 보고 싶을 때

결과 (예상):

GROUP BY를 썼다면 Sales와 Engineering 두 줄만 남았겠지만, OVER()를 쓰니 모든 직원 정보가 그대로 유지되면서 부서 총합이 옆에 붙었습니다.
순위 함수 (Ranking Functions)
파티션 내에서 각 행의 순위를 매길 때 사용합니다.
ROW_NUMBER(): 파티션 내에서 순서대로 고유한 번호를 매김 (1, 2, 3, 4)
RANK(): 순위를 매김. 동점자가 있으면 같은 순위를 부여하고 다음 순위는 건너뜀 (1, 2, 2, 4)
DENSE_RANK(): RANK()와 비슷하지만, 동점자 다음 순위를 건너뛰지 않음 (1, 2, 2, 3)
NTILE(n): 파티션 내의 데이터를 n개의 그룹으로 나누어 그룹 번호를 부여
예시: 부서별로 급여가 높은 순서대로 순위를 매기고 싶을 때

분석/오프셋 함수 (Analytic/Offset Functions)
파티션 내에서 현재 행을 기준으로 앞, 뒤, 또는 처음/마지막 행의 값을 가져올 때 사용합니다.
LAG(col, n, default): 현재 행보다 n번째 이전 행의 col 값을 가져옴
LEAD(col, n, default): 현재 행보다 n번째 다음 행의 col 값을 가져옴
FIRST_VALUE(col): 파티션 내의 첫 번째 행의 col 값을 가져옴
LAST_VALUE(col): 파티션 내의 마지막 행의 col 값을 가져옴
예시: 부서 내에서 바로 다음으로 급여를 많이 받는 사람과의 급여 차이를 보고 싶을 때

결론
OVER()는 SUM()에만 국한되지 않습니다.
OVER()는 SQL에서 데이터를 분석하고, 순위를 매기고, 행 간의 관계를 계산하는 등 매우 정교한 작업을 가능하게 하는 핵심적인 문법입니다. 시니어 개발자로서 이 기능을 잘 이해하고 활용하면 복잡한 쿼리를 훨씬 간결하고 효율적으로 작성할 수 있습니다.
Last updated