SELECT
*
FROM
animal_ins
ORDER BY
animal_id
;
SELECT
animal_id
, animal_type
, datetime
, intake_condition
, name
, sex_upon_intake
FROM
animal_ins
ORDER BY
animal_id
;
-작성한 쿼리: 중첩(일반) 서브쿼리
SELECT
food_type
, rest_id
, rest_name
, favorites
FROM
rest_info
WHERE
(food_type
, favorites) IN (
SELECT
food_type
, MAX(favorites) AS favorites
FROM
rest_info
GROUP BY
food_type
)
ORDER BY
food_type DESC
;
/*전략*/
WHERE favorites IN (
SELECT
food_type
, MAX(favorites)
FROM
rest_info
GROUP BY
food_type
)
/*후략*/
→ 'IN' 안에서의 SELECT문은 단일컬럼을 반환해야 하므로 WHERE 절에서 조건을 건 컬럼 만큼 SELECT를 해야 한다고 함!
→ WHERE 절에서 서브쿼리를 사용할 시 조건을 건 컬럼을 SELECT절에 그대로 넣자
SELECT
food_type
, rest_id
, rest_name
, favorites
FROM
rest_info ri
WHERE
(food_type
, favorites) IN (
SELECT
food_type
, MAX(favorites) AS favorites
FROM
rest_info max
WHERE ri.food_type = max.food_type
)
ORDER BY
food_type DESC
;
SELECT
ri.food_type
, ri.rest_id
, ri.rest_name
, ri.favorites
FROM
rest_info ri
JOIN (
SELECT
food_type
, MAX(favorites) AS favorites
FROM
rest_info
GROUP BY
food_type
) AS mf
ON ri.food_type = mf.food_type
AND ri.favorites = mf.favorites
ORDER BY
food_type DESC
;
- USING 은 INNER JOIN 경우에 권장
- USING 은 뒤에 추가적으로 AND 조건을 붙일 수 없어 OUTER JOIN 시에 주의해야 함
WITH cte AS (
SELECT
food_type
, MAX(favorites) AS favorites
FROM
rest_info
GROUP BY
food_type
)
SELECT
ri.food_type
, rest_id
, rest_name
, ri.favorites
FROM
rest_info ri
JOIN cte c
ON ri.food_type = c.food_type
AND ri.favorites = c.favorites
ORDER BY
ri.food_type DESC
;
추가로 알아두면 좋은 내용
SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM(
SELECT
FOOD_TYPE, REST_ID, REST_NAME, FAVORITES,
ROW_NUMBER() OVER (PARTITION BY FOOD_TYPE ORDER BY FAVORITES DESC ) AS ROW_NUM
FROM REST_INFO) AS T
WHERE ROW_NUM = 1
ORDER BY FOOD_TYPE DESC
;
WINDOW 함수(순위) 활용
참고하면 좋을 내용
SELECT
category
, price
, product_name
FROM
food_product
WHERE
(category
, price) IN (
SELECT
category,
MAX(price) AS price
FROM
food_product
WHERE
category IN ('과자', '국', '김치', '식용유')
GROUP BY
category
)
ORDER BY
price DESC
;
WITH CATEGORY_MAX AS (
SELECT CATEGORY, MAX(PRICE) MAX_PRICE
FROM FOOD_PRODUCT
GROUP BY CATEGORY
)
SELECT P.CATEGORY, M.MAX_PRICE, P.PRODUCT_NAME
FROM FOOD_PRODUCT P JOIN CATEGORY_MAX M
ON P.CATEGORY = M.CATEGORY AND P.PRICE = M.MAX_PRICE
WHERE P.CATEGORY IN ('과자', '국', '김치', '식용유')
ORDER BY 2 DESC
;
SELECT
CATEGORY
, PRICE
, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE 1=1
AND CATEGORY IN ('과자', '국', '김치', '식용유')
AND PRICE = (
SELECT
MAX(PRICE)
FROM
FOOD_PRODUCT AS F
WHERE F.CATEGORY = FOOD_PRODUCT.CATEGORY
)
ORDER BY
PRICE DESC
;
/* 서브쿼리에서 현재 카테고리와 일치하는 행만 고려해야 하기 때문에
F.CATEGORY = FOOD_PRODUCT.CATEGORY를 사용하여
현재 검토 중인 카테고리에 속하는 행들만 서브쿼리에서 고려함 */
SELECT
f2.category
, max_price
, product_name
FROM
food_product f1
JOIN (
SELECT
category
, MAX(price) AS max_price
FROM
food_product
GROUP BY
category
) AS f2
ON f1.category = f2.category
WHERE
f1.price = f2.max_price
AND f2.category IN ('과자', '국', '김치', '식용유')
ORDER BY
max_price DESC
;
SELECT
CATEGORY
, PRICE
, PRODUCT_NAME
FROM
(
SELECT
*
, RANK() OVER(PARTITION BY CATEGORY ORDER BY PRICE DESC) RNK
FROM
FOOD_PRODUCT
WHERE
CATEGORY IN ('과자', '국', '김치', '식용유')
) A
WHERE
RNK = 1
ORDER BY
PRICE DESC
;
solution = lambda num1, num2 : int (num1 / num2 * 1000)
→ int로 형변환 하는 이유는 소수점 아래를 제거하기 위함
→ 1000 * num1 // num2
으로 식을 작성하면 처음부터 몫만 계산하기 때문에 형변환 없이도 값을 얻을 수 있음!
(미미한 차이이지만 int에 비해 처리 시간도 빠르다고 함)
-- 1번
def solution(num1, num2):
return int(num1 / num2 * 1000)
-- 2번
def solution(num1, num2):
answer = int(num1 / num2 * 1000)
return answer
Q. 1번 코드에선 지역변수 answer를 활용하지 않았는데요, 혹시 지역변수가 없으면 좋은 점이 있을까요?
A. 변수를 저장하기 위해선 비용이 듭니다. 비용이 늘면 시스템 성능의 저하가 올 수 있습니다. 또한 함수화 된 코드는 굳이 변수에 담지 않더라도 return 값으로 주면, 차후에 x = solution(someting) 같은 형태로 불러와서 사용이 가능하니, 재사용이 없는 함수 내 지역변수는 굳이 변수에 담지 않는 것을 추천합니다.
SELECT department, COUNT(employee_id)
FROM employees
GROUP BY department
HAVING COUNT(employee_id) > 5;
SELECT department
FROM employees
GROUP BY department
HAVING COUNT(employee_id) > 5;
팀 과제를 안일하게 한 나... 반성해야 할 점이 너무 많다...
데이터의 탐색적 분석, EDA (Exploratory Data Analysis)는 거시적으로 ‘우리가 사용할 데이터는 어떻게 생겼는지’를 면밀히 파악하는 과정입니다. 크게 결측치처리, 이상치처리, 시각화로 구성됩니다. 이는 SQL 에서 NVL, TRIM, IFNULL등 함수사용을 통해 진행해볼 수 있습니다. 통계적 기법, 추가 핸들링을 위해 주로 Python 라이브러리를 활용하게 됩니다.
데이터분석은 물론 숫자를 기반으로 해석되고, 통계적 기법, 머신러닝 등이 활용되지만 개념적인 의미를 놓치지 말아야 합니다. (예를들어 카테고리 값이 비어있을 때, 이를 최빈값대체를 할 수 없다 등)
평균을 대부분 잘 구해주셨으나, 우리는 평균이 가지는 위험성을 인지해야 합니다. 이를테면, 10점, 10점, 10점, 10점, 100점이 있다고 가정해보겠습니다. 이렇게 합계를 구하게 되면 140/5 = 28점이 평균으로 계산되는데, 대부분의 학생들은 10점으로 분포되어 있습니다. 이처럼 평균은 관측값으로 주요 활용되지만, 그 분포를 파악하는 데에 한계점이 있습니다.
MySQL 에서는 PERCENT_RANK 라는 함수를 통해 중앙값이라는 개념을 구할수 있는데, 중앙값이란 데이터를 크기에 따라 나열했을 때, 가장 중앙에 있는 수를 의미합니다. 즉 10점이 됩니다. 해당 내용은 차주에 학습할 예정으로, 참고해주시면 좋을 것 같습니다.
With 구문은 하나의 테이블을 여러 번 조회할 때 사용됩니다. JOIN, DISTINCT 등의 FUNCTION은 다소 많은 연산량을 차지하게 됩니다. 우리가 자주 사용하는 테이블을 임시로 저장해 두고(메모리에 올려두고), 필요한 경우에 따라 데이터를 가져올수 있게 된다는 점을 기억해주시면 좋겠습니다.
결측치에 대한 부분을 많이 다뤄주셨는데, 실제로 데이터 수집 과정에서 미리 data pipeline 을 설계하고 수집하기 때문에 추가적인 업데이트가 어려운 것이 현실입니다. 데이터가 중복적재 되거나, 유실되는 경우는 꽤 많다고 첨언드리겠습니다.
SQL 문법은 대단히 어렵지는 않습니다. 다만, 원하는 데이터를 추출하기 위해 query 를 정확하게 작성하는 것이 중요합니다.
SQL 은 분명 데이터분석가의 가장 기본적인 스킬입니다. QUERY 라는 질의어 중 가장 대중화 되어있죠. 대부분의 데이터분석가 코딩테스트는 sql로 진행됩니다. 코드카타를 9-10시에 꼭 풀어주시길 바랍니다.
코딩을 위해 VisualStudio Code 를 추천드립니다. 탭을 통해 sql을 구조적으로 작성하시는 데 도움이 될 것 같습니다.