인프런 커뮤니티 질문&답변

박갑순님님의 프로필 이미지

작성한 질문수

초보자를 위한 BigQuery(SQL) 입문

총 정리 문제 풀이 4~5번

총 정리 문제 풀이 5번에 관해 질문

해결된 질문

24.05.28 00:05 작성

·

160

0

안녕하세요.

총 정리 문제 풀이 5번의 선생님의 쿼리와, 해설을 보기 전에 개인적으로 써본 쿼리의 각각의 결과가 달라 어디서 오류를 범했는지 알고 싶어 질문합니다.

 

선생님께서 쓰신 쿼리는 다음과 같았습니다.

WITH에서 먼저 trainer_pokemon과 pokemon을 JOIN한 후, 마지막에 trainer를 JOIN하셨습니다.

결과는 Kyle의 포켓몬 공격력+방어력 총합 1951였습니다.

WITH total_stats AS (
SELECT
	tp.trainer_id,
	SUM(p.attack + p.defense) AS total_stat,
FROM basic.trainer_pokemon AS tp
LEFT JOIN basic.pokemon AS p
ON tp.pokemon_id = p.id
GROUP BY
	tp.trainer_id
)
SELECT
	t.name,
	ts.trainer_id,
	ts.total_stat
FROM total_stats AS ts
LEFT JOIN basic.trainer AS t
ON ts.trainer_id = t.id
ORDER BY total_stat DESC
LIMIT 1

 

그리고 저는 다음과 같이 썼습니다.

선생님의 순서와 다르게, WITH에서 먼저 trainer_pokemon과 trainer를 JOIN한 후, 마지막에 pokemon을 JOIN했습니다.

결과는 Kyle의 포켓몬 공격력+방어력 총합 1856였습니다.

WITH pokemon_cnt_table AS(
SELECT
  t.id,
  t.name,
  tp.pokemon_id,
  COUNT(tp.id) AS pokemon_cnt,
FROM
  `basic.trainer_pokemon` AS tp
LEFT JOIN
  `basic.trainer` AS t
ON tp.trainer_id = t.id
GROUP BY
  t.id,
  t.name,
  tp.pokemon_id
)
SELECT
  pct.id,
  pct.name,
  SUM(attack) AS attack_sum,
  SUM(defense) AS defense_sum,
  SUM(attack + defense) AS a_plus_d_sum,
FROM
  pokemon_cnt_table AS pct
LEFT JOIN
  `basic.pokemon` AS p
ON pct.pokemon_id = p.id
GROUP BY
  pct.id,
  pct.name
ORDER BY
  a_plus_d_sum DESC
LIMIT 1

 

결과가 달라진 이유에 대해, 제 나름대로 생각해 본 것은, JOIN의 순서가 달라 WITH 내의 1) SELECT, 2) FROM ON의 키도 다른 점이 출력 데이터에 영향을 준 것이 아닐까 하는 것입니다.

JOIN의 순서 차이로 결과가 달라질 수 있을까요?

제가 작성한 쿼리의 오류에 대한 확인이 번거로우시다면, 결과에 대한 JOIN 순서 차이의 영향 유무에 대해서만 답해 주셔도 감사하겠습니다.

 

미리 감사합니다.

 

답변 2

0

카일스쿨님의 프로필 이미지
카일스쿨
지식공유자

2024. 06. 03. 12:30

안녕하세요! 정리 문제 풀이를 푸셨군요..!

이 부분은 데이터 검증 부분과 결합해서 생각해보시면 좋습니다. 중간 중간에 데이터가 어떻게 저장되어 있을까요? 그것을 확인할 수 있는 쿼리를 작성해보시고 검증을 해보는 것도 좋은 경험일 것 같아 말씀드려요

JOIN이 있는 SELECT 문에서 컬럼을 지정하지 않고 별을 쓰시고, WHERE 조건에 특정 트레이너 이름을 지정해서 데이터를 비교해보시면 왜 다른 결과가 나왔는지 알 수 있을거에요. 추가적으로 답변해주시면 저도 그것에 대해 답변드리면서 정리해드릴게요-!

0

인프런 AI 인턴님의 프로필 이미지

2024. 05. 29. 00:11

안녕하세요, 인프런 AI 인턴입니다.

질문해 주신 JOIN 순서의 차이가 결과에 영험을 줄 수 있는지에 대한 질문에 답드리겠습니다.

네, JOIN의 순서는 결과에 영향을 줄 수 있습니다. 특히, 사용하신 데이터의 경우와 같이 여러 테이블 간의 관계가 복잡할 때, 어떤 순서로 테이블을 조인하느냐에 따라 최종 결과가 달라질 수 있습니다. 각 JOIN이 진행될 때마다 포함되는 행과 제외되는 행이 결정되기 때문에, 데이터의 구조와 조인되는 테이블의 순서에 따라 최종 집계 결과에 차이가 발생할 수 있습니다.

구체적으로, 첫 번째 쿼리에서는 trainer_pokemonpokemon을 먼저 조인하여 포켓몬의 공격력과 방어력 합계를 구한 후, 이 결과를 trainer와 조인하여 트레이너의 이름을 가져왔습니다. 이 경우에는 ‘trainer_pokemon’ 테이블과 ‘pokemon’ 테이블 간의 관계를 토대로 해당 트레이너의 포켓몬들의 스탯 합계를 먼저 계산하기 때문에 정확한 공격력과 방어력의 총합을 구할 수 있습니다.

반면, 두 번째 쿼리에서는 trainer_pokemontrainer를 먼저 조인한 후 pokemon 테이블을 조인했습니다. 이 과정에서 ‘trainer_pokemon’ 테이블과 ‘trainer’ 테이블 간의 조인으로 인해 특정 트레이너에 대한 포켓몬 정보가 먼저 결합되고, 이후에 ‘pokemon’ 테이블이 조인되면서 포켓몬의 스탯 정보가 추가됩니다. 이렇게 조인 순서가 변경되면 중간 집계 과정에서 데이터의 처리 방식이 달라져 최종 결과에 차이를 불러일으킬 수 있습니다.

따라서, 결과가 달라진 근본적인 원인은 JOIN의 순서 차이가 맞습니다. 데이터베이스 쿼리 설계 시 조인의 순서를 신중하게 고려하여 원하는 결과를 얻을 수 있도록 주의가 필요합니다.

감사합니다.