ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SQL] data.world tutorial SQL CASE 예제 풀이
    데이터 분석/DB & SQL 2020. 5. 2. 18:12

    컬럼에 대해서 CASE 분기 태울 때 활용한다. 

    https://docs.data.world/documentation/sql/concepts/intermediate/CASE.html

     

    CASE

    Learn about the CASE expression in this SQL tutorial. Visit for a full course on learning the basics of SQL.

    docs.data.world

     

    CASE 의 활용

    CASE is a general conditional expression that allows you to 
    - test data for equality with a specified value,  특정값과 동치여부 확인
    - partition data into ranges,  데이터를 범위에 따라 나눔(파티션) 
    - or perform any other conditional check against the data. 조건문 수행

     

    Simple Syntax
    대상필드가 모두 동일할 때 요렇게 간단하게 써도 된다.

    CASE 대상필드
    WHEN a THEN A 
    WHEN b THEN B (...) 
    ELSE C (opt, if omitted null)
    END

     

    General Syntax
    하지만 현실적으로는 여러 컬럼에 대해 조건을 체크할 가능성이 높으므로 아래와 같이 처리하는 것이 보편적이다. 

    CASE 
    WHEN a THEN A
    WHEN b THEN B (...) 
    ELSE c (opt, if omitted null)
    END

    A, B ...  WHEN THEN 문 순서대로 수행한다. 
    ELSE 는 생략 가능하며, WHEN 조건에 모두 부합하지 않고 ELSE 문이 생략되면 null 로 리턴한다. 
    ELSE 는 생략 가능은 하지만, 명시성을 위해 기입해주는 것이 좋다. 

     


    1. 요구사항 검토

    Write a query against the observations_cleaned table using the general CASE expression

    - 데이터 소스: observations_cleaned 

     

    to return the patient and description columns, the average of the value column, and unit column along with a new column labeled BMI category.

    - 데이터 결과 컬럼: patient, description, avg(value), unit, BMI category

     

    The results are only for the records where the description is Body Mass Index.

    - 데이터 셋 조건: description = "Body Mass Index"

     

    The entries in the BMI category column should be Underweight for values under 18.5, Healthy for values from 18.5 to 24.9, Overweight for values of 25-29.9, and Obese for values over 30.

    - 컬럼 BMI category 카테고리 범주화: CASE 문

     

    Category 의 대표: BMI

     

    2. 데이터셋 확인

    observations_cleaned 테이블을 확인한다. 

    SELECT * FROM observations_cleaned
    WHERE description = "Body Mass Index" -- 7296

    SELECT DISTINCT patient FROM observations_cleaned
    WHERE description = "Body Mass Index" -- 1099

    SELECT DISTINCT units FROM observations_cleaned
    WHERE description = "Body Mass Index" -- 1, kg/m^2 only

    1099 명의 환자에 대해 BMI 지표는 7296 번 측정되었다. 한 환자에게도 BMI 를 여러번 측정했다는 점을 알 수 있다.
    BMI 만 추출했으므로 description = "Body Mass Index", units = "kg/m^2" 로 동일하다.

     

    3. 쿼리 구조 검토

    to return the patient and description columns, the average of the value column, and unit column along with a new column labeled BMI category.

    - AVG 값이 필요하니 value 에 대한 평균값 집계 GROUP BY 가 필요하다. 
    아마도 집계 기준은 patient 로 추정된다. 

    - AVG 외 나머지 컬럼도 집계결과로 편입시켜서 집계한다. 
    description, units 는 저 집계대상 데이터셋의 모든 값이 동일한 값이다: Body Mass Index, cm/m^2 
    그래도 추가해달라고 요청했으니, String 에 대한 집계함수로 MAX 처리한다. (문자열도 알파벳 순서 기준으로 MIN/MAX 집계함수를 수행할 수 있다.) 

    - BMI category 범주화를 해야하니 CASE 문이 필요하다. 

     

    4. 쿼리 작성

    SELECT patient,
    MAX(description),
    AVG(value) AS `Avg BMI`,
    MAX(units),
    CASE
    WHEN value < 18.5 THEN "Underweight"
    WHEN value >= 18.5 AND value < 25 THEN "Healthy"
    WHEN value >= 25 AND value < 30 THEN "Overweight"
    WHEN value >= 30 THEN "Obese"
    END AS `BMI category`

    FROM observations_cleaned
    WHERE description = "Body Mass Index"

    GROUP BY patient, `BMI category`

     

    그런데 노랑 알럿이 뜬다.
    - Field of aggregated query neither grouped nor aggregated: line 5, column 8 --> CASE 문

    GROUP BY 집계를 활용하면, 결과 데이터셋에 집계기준 (grouped) 이거나 집계결과 (aggregated) 이거나 둘 중 하나이기를 권장한다.

    저 Body Mass Index 는 집계 기준일까? 결과일까? 사용자한테 한번 더 물어보자. 환자마다 여러번 BMI 를 측정했고, BMI 카테고리가 변경될 수 있으므로, 집계기준으로 해달라는 요청을 추가로 받았다.  GROUP BY 기준으로 BMI category 를 추가한다. 

     


     

    요구사항은 정말 한 문장으로 압축되기 힘들어 보인다.  (심지어 튜토리얼 조차도 명확하지 않다니) 
    앞으로 사용자가 쿼리 요구사항을 제대로 안 줘도 너무 원망하지는 말아야겠다. ㅇ__ㅇ;;

    댓글

Designed by Tistory.