BOAZ SQL 스터디(2)-intermediate SQL(1)
업데이트:
SQL Aggregate Functions
Apple stock prices dataset를 사용할 것이다.
Aggregate functions in SQL
COUNT
SUM
MIN
/MAX
AVG
row를 기준으로 수행하는 산술연산은 이전 절에서 다뤘다. agg func은 col의 전체 row를 기준으로 수행한다.
COUNT
Counting all rows
COUNT(1)
은 COUNT(*)
과 같다.
Counting individual columns
SELECT COUNT(high)
FROM tutorial.aapl_historical_stock_price
high
column이 not null인 경우만 count한다.
Counting non-numerical columns
SELECT COUNT(date)
FROM tutorial.aapl_historical_stock_price
COUNT
는 단순 non-null 값만 세기 떄문에 구별된(distinct) 값을 세지 않는다.
DISTINCT
로 구별된 값을 가져올 수 있음
결과 컬럼명을 다른 이름으로 바꾸고 싶으면 AS
문을 사용하면 된다.
공백 넣고 싶으면 "
쓰면 된다.
SQL에서
"
는 이렇게만 쓰인다. 반면'
는 여러 방법에서 쓰임
SUM
SELECT SUM(volume)
FROM tutorial.aapl_historical_stock_price
agg func은 수직으로만 적용한다. row로 산술연산 하지 않는다
SUM
에서 null 값은 0으로 처리한다.
MIN / MAX
non-numerical column에서 column type에 따라 연산이 다르다.
MIN
은 가장 작은 수, 가장 빠른 날짜, 사전식으로 가장 빠른 문자. MAX
는 반대이다.
AVG
오직 숫자형 컬럼에만 사용될 수 있다.
NULL을 완벽하게 무시한다.
NULL값을 0으로 생각해서 연산하고 싶으면 추가 구문을 작성해야 한다.
GROUP BY
지금까지의 연산들은 전체 테이블을 기준으로 수행했다. 테이블의 일부분에 수행해야 한다면 GROUP BY
써야 한다.
SELECT year,
COUNT(*) AS count
FROM tutorial.aapl_historical_stock_price
GROUP BY year
여러 컬럼을 GROUP BY
할 수도 있다.
SELECT year,
month,
COUNT(*) AS count
FROM tutorial.aapl_historical_stock_price
GROUP BY year, month
컬럼 이름 대신 숫자로도 접근할 수 있다. 모든 SQL에 적용되는 것은 아님!!
Using GROUP BY with ORDER BY
GROUP BY
는 결과를 순서 상관없이 보여준다. 순서를 고려하고 싶으면 ORDER BY
문 같이 쓰면 된다.
SELECT year,
month,
COUNT(*) AS count
FROM tutorial.aapl_historical_stock_price
GROUP BY year, month
ORDER BY month, year
Using GROUP BY with LIMIT
aggregation은 LIMIT
실행 전에 수행된다. LIMIT
문과 함께 쓸 때 초과된 row를 포함해서 수행된다.
HAVING
WHERE
문은 aggregate 할 컬럼에 대해서는 조건문을 수행할 수 없다. HAVING
문으로 할 수 있다.
SELECT year,
month,
MAX(high) AS month_high
FROM tutorial.aapl_historical_stock_price
GROUP BY year, month
HAVING MAX(high) > 400
ORDER BY year, months
subquery를 통해서도 같은 결과를 얻을 수 있다.
Query clause order
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
DISTINCT
SELECT DISTINCT month
FROM tutorial.aapl_historical_stock_price
여러 컬럼을 포함하면 유니크한 쌍을 전부 보여준다.
SELECT DISTINCT year, month
FROM tutorial.aapl_historical_stock_price
Using DISTICT in aggregations
유니크한 month
의 수를 셀 수 있다.
SELECT COUNT(DISTINCT month) AS unique_months
FROM tutorial.aapl_historical_stock_price
DISTINCT
는 SELECT
문 말고 agg func 안에 들어간다. SUM
과 AVG
도 사용 가능하다.하지만 MAX
/ MIN
은 DISTINCT
를 쓸 필요가 없다.
DISTINCT performance
특히 agg에서 DISTINCT
를 사용하면 쿼리 속도가 꽤 느려질 수 있습니다.
CASE
SQL의 if / then 구문이다.
SELECT player_name,
year,
CASE WHEN year = 'SR' THEN 'yes'
ELSE NULL END AS is_a_senior
FROM benn.college_football_players
- 조건문을 체크한다
- TRUE이면 THEN 문을 실행
- FALSE이면 null 값을 남긴다.
- AS로 컬럼명을 지정한다.
multiple conditions to a CASE statement
SELECT player_name,
weight,
CASE WHEN weight > 250 THEN 'over 250'
WHEN weight > 200 AND weight <= 250 THEN '201-250'
WHEN weight > 175 AND weight <= 200 THEN '176-200'
ELSE '175 or under' END AS weight_group
FROM benn.college_football_players
WHERE
문과 같이 AND
와 OR
로 조건문을 수행할 수 있다.
SELECT player_name,
CASE WHEN year = 'FR' AND position = 'WR' THEN 'frosh_wr'
ELSE NULL END AS sample_case_statement
FROM benn.college_football_players
review
CASE
문은SELECT
안에 있어야 한다.CASE
는WHEN
,THEN
,END
를 꼭 포함해야 하고,,ELSE
는 선택적으로 포함할 수 있다.
CASE with aggregate functions
CASE
는 agg func와 함께 쓰면 더 유용하다.
SELECT CASE WHEN year = 'FR' THEN 'FR'
ELSE 'Not FR' END AS year_group,
COUNT(1) AS count
FROM benn.college_football_players
GROUP BY CASE WHEN year = 'FR' THEN 'FR'
ELSE 'Not FR' END
그냥 WHERE
절 써도 비슷한 결과를 얻을 수 있다.
SELECT COUNT(1) AS fr_count
FROM benn.college_football_players
WHERE year = 'FR'
그러나, WHERE
는 하나의 조건을 통해 나온 결과만 카운트 가능하다. 여러 조건을 통해 나온 여러 쌍을 카운트하려면
SELECT CASE WHEN year = 'FR' THEN 'FR'
WHEN year = 'SO' THEN 'SO'
WHEN year = 'JR' THEN 'JR'
WHEN year = 'SR' THEN 'SR'
ELSE 'No Year Data' END AS year_group,
COUNT(1) AS count
FROM benn.college_football_players
GROUP BY 1
group by로 전체 CASE
구문을 써도 되고, 숫자도 되고, AS
문으로 만든 alias도 된다.
SELECT CASE WHEN year = 'FR' THEN 'FR'
WHEN year = 'SO' THEN 'SO'
WHEN year = 'JR' THEN 'JR'
WHEN year = 'SR' THEN 'SR'
ELSE 'No Year Data' END AS year_group,
COUNT(1) AS count
FROM benn.college_football_players
GROUP BY year_group
전체 CASE
구문을 반복해서 쓰려면, GROUP BY
절에서 AS
문을 제거해야 한다.
SELECT CASE WHEN year = 'FR' THEN 'FR'
WHEN year = 'SO' THEN 'SO'
WHEN year = 'JR' THEN 'JR'
WHEN year = 'SR' THEN 'SR'
ELSE 'No Year Data' END AS year_group,
COUNT(1) AS count
FROM benn.college_football_players
GROUP BY CASE WHEN year = 'FR' THEN 'FR'
WHEN year = 'SO' THEN 'SO'
WHEN year = 'JR' THEN 'JR'
WHEN year = 'SR' THEN 'SR'
ELSE 'No Year Data' END
CASE
문과 aggregateion func를 섞어 쓰는 건 까다롭다. 처음에는 CASE
문만 먼저 작성하고 실행시켜 보자.
SELECT CASE WHEN year = 'FR' THEN 'FR'
WHEN year = 'SO' THEN 'SO'
WHEN year = 'JR' THEN 'JR'
WHEN year = 'SR' THEN 'SR'
ELSE 'No Year Data' END AS year_group,
*
FROM benn.college_football_players
이후에 *
을 aggregation과 GROUP BY
문으로 바꾸자.
댓글남기기