오늘은 PostgreSQL에서 Join을 활용하는 예제를 살펴보려고 합니다. 제가 실무에서 겪은 이슈 중에 Left Join을 사용하여 손쉽게 쿼리를 작성했던 것을 다른 예시를 통해서 해결방법을 보여드리려고 합니다😁
개요
앞서 말씀드렸듯이, 실무에서 겪었던 이슈를 Join을 통해 손쉽게 해결했던 경험을 말씀드리려고 합니다. 상황은 mybatis를 사용하지 못하고 오직 쿼리로만 해결해야 했던 이슈입니다. 이슈를 간단하게 설명드리면, 고객사에서 기존에 진행했던 설정 방식과 달리 다른 방식으로 마이그레이션 하는 작업이기 때문에, 따로 Java 프로젝트를 실행시키는 것이 아닌 DB 구조만 바꾸는 과정이었습니다.
💡 제가 다니는 회사는 DBPatcher라는 프로젝트가 있어서 원하는 쿼리를 DBPatcher 프로그램을 통해 실행시킬 수 있는 구조입니다.
상황 예시📙
학교 학생 테이블
student_t | name | age | id |
1 | 김하늘 | 17 | 1 |
2 | 이무진 | 17 | 2 |
... | ... | ... | ... |
학교 학생 서브 테이블
student_sub_t | id | 좌우명 |
1 | 0 | 멋지게 살자! |
... | ... | ... |
... | ... | ... |
위와 같이 학생 테이블과 학생 서브 테이블이 있다고 간주해봅시다. 교장선생님은 자신의 좌우명인 '멋지게 살자!'를 적어 놓고, 학생들도 나중에 각자 자신만의 좌우명을 학생 서브 테이블에 작성하기를 원하십니다. 하지만, 해당 학교 개발자가 오늘까지만 일해서 모든 학생의 좌우명을 Default 값으로 교장선생님의 좌우명인 '멋지게 살자!'로 해놓고 추후에 개인적으로 변경하기로 합니다.(말도 안 되지만 실무에서는 고객사가 언제 바꾸고 싶은지 몰라서..😅)
💡 모든 학생의 id 값을 이용하여 학생 서브 테이블에 교장선생님의 좌우명을 기본값으로 넣어놓으려면 쿼리를 어떻게 짜야 할까요?
첫 번째 시도📘
1. 교장선생님의 좌우명을 조회하는 쿼리를 구성한다.
SELECT 좌우명 FROM student_sub_t WHERE id = 0;
// 결과 : 멋지게 살자!
2. 학생들의 id 값을 조회하는 쿼리를 구성한다.
SELECT id from student_t;
// 결과 1,2, .... 여러개
3. INSERT 문을 이용하여 학생 서브 테이블에 학생들의 좌우명을 Default 값으로 교장선생님의 좌우명으로 넣어 놓는다.
INSERT INTO student_sub_t (id, 좌우명)
VALUES (SELECT id FROM student_t, SELECT 좌우명 FROM student_sub_t WHERE id = 0);
// 결과 : ERROR
에러 내용은 more than one row returned by a subquery used as an expression입니다.
에러가 왜 생길까요? 에러를 해석해 보면 하위 쿼리에서 두 개 이상의 로우를 리턴한다는 이야기입니다. 어떻게 보면 당연한 에러인데, 학생들의 id 값은 전교생의 id 값들을 리턴합니다. 즉, 전교생 중 어떤 학생의 id 값을 넣어야 하는지 모른다는 뜻이죠
이럴 때는 어떻게 해야 할까요?
Join 사용📒
INSERT를 학생 한 명 한 명씩 나눠서 넣는다는 생각을 버려야 합니다. '처음에는 저도 반복문을 사용해서 넣어야 하나?' 생각했지만, 각 학교마다 전교생이 몇 명인지 세는 로직도 필요하고, 하물며 mybatis를 쓸 수 없어서 반복문 자체를 사용할 수가 없었습니다.
로우 하나하나를 각기 넣는 것이 아니라 JOIN을 사용하여 student_t와 교장선생님의 좌우명 '멋지게 살자'를 붙여 놓고 한 번에 모든 학생들을 INSERT 해줘야 합니다.
INSERT INTO student_sub_t (id, 좌우명)
VALUES (
SELECT id FROM student_t
LEFT JOIN (
SELECT 좌우명 FROM student_sub_t WHERE id = 0
)
);
결과
student_sub_t | id | 좌우명 |
1 | 0 | 멋지게 살자! |
2 | 1 | 멋지게 살자! |
3 | 2 | 멋지게 살자! |
... | ... | ... |
생각보다 간단하죠? 조건문 자체가 별로 없기 때문에, 간단해 보일 수 있지만 사실 '로우 하나하나를 넣어야겠다'라는 생각에서 '한 번에 모든 데이터를 넣어야겠다'라는 생각으로 바꿔서 해결하는 것은 초보자 입장에서 어려울 수도 있을 것 같습니다😂
이 밖에도 Join은 정말 많은 곳에서 활용됩니다. 다음에는 조금 더 심화 과정으로 좋은 예시를 가지고 찾아뵐게요😃
👨👩👦👦 오픈채팅방 운영
취업을 준비하는 예비 개발자분들을 위한 질문&답변할 수 있는 공간을 만들었습니다. 취업과 이직을 하기 위해서 어떤 걸 중점적으로 준비해야 하는지부터 포트폴리오&이력서 작성법 등 다양한 질문들을 받고 답변을 드립니다. 참여하셔서 다양한 정보 얻고 가시면 좋을 것 같네요😁
참여코드 : 456456
https://open.kakao.com/o/gVHZP8dg
👨💻 전자책 출간
아울러 제가 🌟비전공자에서 2년 만에 보안 전문 중견기업으로 이직 한 방법들을 정리한 전자책을 출간하게 되었습니다. 어떤 걸 공부해야 하는지, 이직을 위해서 무엇을 준비해야 하는지, 제가 받았던 기술 면접 리스트 등 다양한 목차로 구성되어 있습니다. 또한, 구매 시 1:1 채팅을 이용하여 포트폴리오 첨삭을 도와드리고 있습니다. 🐕전자책으로 얻은 모든 수익은 유기견 센터 '팅*벨 입양센터'에 후원될 예정입니다. 관심 있으신 분들은 아래 링크를 참고해 주세요😁
'TIL' 카테고리의 다른 글
[Java] csv 파일 프로그램 여러가지 Tip (0) | 2023.09.14 |
---|---|
Java String, StringBuilder, StringBuffer 차이와 장단점 (2) | 2023.08.21 |
PostgreSQL JSON 데이터 활용 II (7) | 2023.06.01 |
PostgreSQL JSON 데이터 활용 (0) | 2023.05.30 |
AOP(Aspect-Oriented Programming) 파헤치기 (0) | 2022.06.22 |