작성
·
332
0
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
안녕하세요 강사님.
질문이 좀 있습니다.
a,b,c,d table 과 id 컬럼이 있다고 가정
1) 여기서 [1.1] 쿼리는 실행 계획으로 치면
a,b,c를 이너조인해서 만든 데이터셋으로 d와 아우터조인해서 결과 도출.
이렇게 이해하고 있습니다.
그런데, 여기서 궁금한것이 LEFT OUTER JOIN은 서술 왼쪽 테이블이 드라이빙 고정으로 알고 있습니다.
그래서, [1.2] 쿼리는 실행 계획으로 치면
a,b를 이너조인해서 만든 데이터셋으로 d와 아우터조인해서 데이터 셋을 새로만듬.
그리고 , c와 이너조인 진행 이렇게 이해하면 될까요?
2)
1.1과 1.2처럼 아우터조인의 서술 위치에 따라서 결과값에 대한 데이터가 달라질수 있나요?
결국 a.id와 조인하기 때문에 해당 기준으로 데이터를 뽑아서
어디에 서술하던지 데이터는 달라질수 없는거같은데 제가 이해한게 맞는지 질문드립니다.
3)
2번을 질문드린 이유중 하나인데요.
아우터 조인을 쓰면 테이블의 드라이빙 순서가 고정되버리니까 서술한 위치에 따라서 실행계획이 바뀔테고
그러면 데이터가 변경될수도 있는 사례가 있을까요?
실행계획은 아무리 바뀌어도 데이터의 영향을 주는건 없는걸로 알지만 , 자꾸 뭔가 헷갈려서 질문드립니다.
4)
a.id = b.id on b.id =c.id on c.id =d.id 이런식으로 조건을 주면
이너 조인은 상관 없겠지만 아우터 조인을 진행할 때는 데이터가 달라질거 같은데
보통은 아우터 조인 쿼리를 작성할 때 조인 조건을 어떻게 줘야하나요?
제가 적은 예시처럼 쿼리를 짜나요??
질문이 두서 없고 너무 많아서 죄송합니다..
강사님 강의를 통해 확실하게 잡고 가지 않으면 추후에 또 다시 공부를 해야할 거 같아 질문드립니다.
[1.1]
select *
from a
INNER JOIN b
ON a.id = b.id
INNER JOIN c
ON a.id = c.id
LEFT OUTER JOIN d
ON a.id = d.id;
[1.2]
select *
from a
INNER JOIN b
ON a.id = b.id
LEFT OUTER JOIN d
ON a.id = d.id
INNER JOIN c
ON a.id = c.id;
답변 3
0
강사님 진짜 성심성의껏 답변주셔서 감사드리나
혹시 1,2,3,4번 질문드린거로 답변주실수있으실까요?
답변주신거로는 아직 이해가 잘 안돼서 한번 더 질문드립니다..
바쁘신데 죄송합니다;;
안녕하세요 강사님
4번 사례를 질문드리려던 의도는 제가 올린 쿼리는 전부 on절이 a 기준으로 조인이되고있습니다.
a.id = b.id , a.id = c.id , a.id =d.id
그런데 ,궁금했던것은 저렇게 조인절을 기술해도 전부 Inner join이면 상관없으나 강사님이 지적해주신 부분을 토대로 보면 outer join이 들어갈 경우 해당 조인절은 잘못 기술된것으로 이해하였습니다.
1)
근데 여기서 궁금한것이, 밑에 쿼리를 예시로 들면 A기준으로 전부 뽑는게 아닌 A와 B를 이너조인한 결과를 OUTER로 해서 뽑겠다.
이러면 밑에 쿼리도 맞는것이 아닌지 질문드립니다.
select *
from a
LEFT OUER JOIN b.id =c.id
2)
이게 전에 질문했던 4번과 같은 질문인데요.
select *
from a
LEFT OUER JOIN a.id = c.id <- 여기서 조인절을 a기준
즉, 왼쪽에 조인절을 전부 a로 기술해버리는 식의
쿼리 기술법을 제가 사이트에서 본적이 있어서 질문드립니다.
b.id = c.id가 아닌 왜 전부 a로 기술해버리는것인지 그냥 개발자의 쿼리 미숙으로 인하여 저런식으로 기술하는건지 아님 다른 의도가 있어서 저렇게 기술하는 건지 좀 궁금하여서 질문드렸습니다.
감사합니다.
1)
근데 여기서 궁금한것이, 밑에 쿼리를 예시로 들면 A기준으로 전부 뽑는게 아닌 A와 B를 이너조인한 결과를 OUTER로 해서 뽑겠다.
이러면 밑에 쿼리도 맞는것이 아닌지 질문드립니다.
select *
from a
=> 맞긴 하지만, 가능하면 이런식으로 inner join과 left outer join을 같이 안 사용하셨으면 합니다. 이유는 이전 답변에서도 말씀드렸듯이 다른 사람이 보면 작성자의 의도가 헷갈립니다.
2)
이게 전에 질문했던 4번과 같은 질문인데요.
select *
from a
LEFT OUER JOIN a.id = c.id <- 여기서 조인절을 a기준
즉, 왼쪽에 조인절을 전부 a로 기술해버리는 식의
쿼리 기술법을 제가 사이트에서 본적이 있어서 질문드립니다.
=> 1번 쿼리와 결과가 같을 겁니다. iINNER JOIN b on a.id = b.id 이므로 결국은 a.id와 b.id가 같은 것이 대상이 되기 때문입니다.
0
안녕하십니까,
오, AI 인턴이 열일하고 있었군요. AI 인턴은 제가 설정하는 것이 아니라 인프런에서 자동으로 돌아가는 거라, 제가 어떻게 할 수가 없습니다. 그냥 보조적인 답변이 하나 더 간다고 생각해 주시면 좋을 것 같습니다.
핵심은 OUTER JOIN과 INNER JOIN은 섞어서 쓰면 OUTER JOIN 집합이 보존되는게 아니라 INNER JOIN 레벨로 최종 만들어 집니다. 이게 뒤 강의를 보시면 OUTER JOIN을 사용할 때 유의해야 할 부분으로 예제로 설명을 드립니다.
OUTER JOIN -> INNER JOIN 과 같이 조인하면 결국 최종은 INNER JOIN 수행할 때 OUTER JOIN이 적용된 부분이 INNER JOIN시 조인 결과에서 제외 될 수 있습니다.
예를 들어
select *
from a
LEFT OUTER JOIN b on a.id = b.id
라고 하면 b.id는 없는 데이터지만 집합 a는 보존되기 때문에 a.id는 데이터가 있을 수 있습니다. 하지만 뒤에 b.id = c.id 를 조인할 때 inner join을 하기 때문에 outer로 보존된 a.id는 조인 대상에서 사라질 수 있습니다.
때문에 특정 테이블 a 만을 계속 보존해 나가기 위해서 모든 조인을 다 아래와 같이 outer 로 바꿔줘야 합니다.
select *
from a
LEFT OUTER JOIN b on a.id = b.id
LEFT OUTER JOIN c on b.id = c.id
글로 적은 답변이 조금 이해에 어려 울 수 있지만, 뒤 강의에서 설명드리오니 참조하시면 도움이 될 것 같습니다.
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
gomadafter님의 질문은 조인의 순서와 방향, 그리고 OUTER JOIN 사용 시 결과값에 대한 변화와 실행계획의 변화 가능성에 대한 것으로 보입니다. 이와 관련하여 두 가지 비슷한 주제의 질문과 답변이 존재합니다.
위의 링크를 참고하여 조인의 방향과 실행 계획에 따른 결과값의 변화에 대한 이해를 심화시킬 수 있습니다. 추가적인 질문이 있으시다면 해당 질문 페이지에서 댓글로 문의하시면 됩니다.
제가 1, 2, 3, 4 로 답변 드리지 않은 이유는 1, 2, 3, 4 와 같은 방식으로 조인을 사용하시면 원하는 결과를 얻지 못할 수 있다는 의미로 말씀드린 겁니다.
지금 1.1, 1.2에서 left table은 a 테이블인데, 이런 방식으로 조인하면 a 테이블이 보존되지 않습니다. 이유는 이전 답변에서 말씀 드린대로 입니다.
예를 들어 아래 sql 에서 a 다음에 b 가 조인 될 거라고 생각할 수 도 있지만, a 다음에 d가 조인될 수도 있습니다. 이건 실행 계획이 정하는 겁니다. 그런데, 다음 조인이 inner join b가 될 경우 b와 조인 되지 않는 a 집합은 보존되지 않습니다. 만약에 다음 조인이 b가 아니라 c가 되어도 c와 조인되지 않는 a 집합은 보존되지 않습니다.
select *
from a
INNER JOIN b
ON a.id = b.id
INNER JOIN c
ON a.id = c.id
LEFT OUTER JOIN d
ON a.id = d.id;
실행 계획이 어떻게 풀리던 결과는 동일합니다. a -> d -> b -> c 또는 a -> b -> c ->d , a ->c->b->d, a->c->d->b 등 어떻게 하든 결과는 동일합니다. a를 거쳐, b 또는 c로 조인하면서 inner join이 되니 left outer 로 보존할 a 집합이 온전히 보전되지 않습니다.
적어주신 유형의 SQL은 사용하지 않는게 바람직합니다(1.1, 1.2 다 마찬가지 입니다). 어느 집합을 left 집합으로 outer로 보존할 것인지 헷갈릴 수 있으며, Left 가 되는 a 테이블이 결국에는 보존이 되지 않으며, 최종적으로는 a , b, c는 모두 inner join된 결과가 도출되기 때문입니다. 부득이 하게 inner join 되어야 하는 특정 집합이 있으면 이들을 인라인 뷰나 with 절로 먼저 감싼 다음에 left outer를 수행하십시요. 예를 들어 a->b 는 inner join이 되고 이 결과 집합이 left outer가 되어야 한다면 이들 조인을 먼저 인라인 뷰나 with 절로 만든 다음에 이 결과를 left outer에 적용하십시요.
위 사항을 인지하시고 1, 2, 3, 4에 대한 답변을 드리면
말씀드린대로 실행계획은 위에서 말씀드린 대로 다양한 방식으로 풀릴 수 있습니다. SQL에 기술된 테이블 순서로 풀리지 않습니다.
2개 SQL의 결과는 동일할 것입니다. 하지만 1.1이든, 1.2와 같은 SQL은 사용하지 않으시는게 좋습니다.
2번과 비슷한 질문 같습니다만, 동일 sql의 실행 계획이 바뀐다고 SQL 결과는 바뀌지 않습니다.
이건 질문을 잘 이해하지 못했습니다. 예시를 다시 들어서 질문해 주셨으면 합니다.