해결된 질문
24.05.25 15:07 작성
·
158
0
안녕하세요, 4-5. 연습 문제 1번
(#트레이너가 포켓몬을 포획한 날짜(catch_date)를 기준으로, 2023년 1월에 포획한 포켓몬의 수를 계산해 주세요.)
의 정답을 보고 의문이 있어 질문 올립니다.
선생님께선 아래와 같이 쿼리를 작성해 주셨는데요. count 함수의 변수, id는 처음부터 고유한 번호인데 distinct를 걸어주신 이유를 알고 싶습니다. (count 결과는 85)
select
count(distinct id) as cnt
from
`basic.trainer_pokemon`
where
extract (year from datetime(catch_datetime, "Asia/Seoul")) = 2023
and extract (month from datetime(catch_datetime, "Asia/Seoul")) = 1
실험적으로, trainer_id를 변수로 쓴 것과, distinct를 걸어서 trainer_id를 변수로 쓴 것의 결과를 확인해 보니, 각각 85, 48이었습니다.
select
count(trainer_id) as cnt,
count(distinct trainer_id) as distinct_cnt
from
`basic.trainer_pokemon`
where
extract (year from datetime(catch_datetime, "Asia/Seoul")) = 2023
and extract (month from datetime(catch_datetime, "Asia/Seoul")) = 1
1명의 트레이너가 2023년 1월에 2마리 이상의 포켓몬을 포획하는 경우도 있을 수 있으니, distinct를 걸어버리면, 1월에 여러 번 포획한 횟수가 1회로 줄어버리지 않을까 생각되는데, 잘못된 곳이 있다면 짚어주셨으면 합니다.
미리 감사합니다.
답변 2
1
2024. 05. 25. 18:19
안녕하세요! 해당 문제에서 id는 PK라서 고유한 값이 맞습니다. 제가 DISTINCT를 사용했던 것은 제 쿼리 작성 습관이 항상 이런 값이 정말 Unique한가 확인하기 위해 DISTINCT를 쓰고 있어요.
해당 문제에선 복잡한 JOIN이 없기 때문에 DISTINCT를 안해도 괜찮지만, 만약 JOIN이 들어가서 데이터가 증가된다면 이런 경우 실수할 수 있기 때문에 DISTINCT을 항상 하곤 합니다. 해당 쿼리에서는 DISTINCT를 여부와 상관없이 85가 나오게 됩니다.
실험적으로 작성해주신 trainer를 COUNT하는 것은 문제의 의도와 다릅니다. 문제에선 포켓몬의 수를 알고 싶었고, 동일한 포켓몬을 잡았어도 별도로 COUNT하는 것을 의도했습니다. 그렇기 때문에 trainer_pokemon(이 테이블에선 하나의 row가 한번의 포획을 의미하기에)의 id를 사용했습니다.
DISTINCT가 없는 경우는 2023년 1월에 포획한 적이 있는 데이터 중 trainer_id가 존재하는 Row 수를 세는 것(해당 데이터는 trainer_id에 NULL이 없기 때문에 동일한 결과가 나옵니다)이고 DISTINCT를 사용한 경우엔 2023년 1월에 포획한 적이 있는 트레이너의 고유한 수를 세게 됩니다. 1월에 여러 번 포획한 횟수가 1회가 되는게 아니라, 1월에 포획한 trainer_pokemon 중에 트레이너의 수가 uniqe해져서 1번이 되게 됩니다.
0
2024. 05. 25. 18:44
공부를 시작한지 3일 밖에 지나지 않았지만, 변수 선택이 항상 발목을 잡게 되는 것 같습니다. 설명을 잘 읽어보니, trainer를 변수로 써선 안 되는 이유, id 앞에 distinct를 써주신 이유도 이해하게 되었습니다. 상세한 설명 정말 고맙습니다.
2024. 05. 25. 22:37
학습 파이팅이에요!!! 🙂 이러면서 실력이 쌓이고 있을거에요 💪