SQL JOIN

노력을 즐기는 사람·2020년 7월 27일
1

사오정 앱개발

목록 보기
4/11

SQL을 짜는건 너무 무섭다. 왜냐면 데이터베이스 수업을 C-를 받았으니깐 사실 소스코드를 작성하는 것보다 쉬운데 SQL을 짜는건 무섭다. 내가 데이터베이스를 너무 몰라서 그런 것 같다. 그도 그럴것이 Spring을 다룰 때는 JPA가 모든 쿼리를 작성해줬다. 나중에 쿼리를 좀 살펴보니 좀 비효율 적이더라 객체 설계를 잘못했나보다 그 이후에 PHP로 학교 과제를 할 때 SQL을 직접 작성해서 JOIN을 해야하는 일이 있었는데 엄청 비효율적인 쿼리를 날렸다. 시간에 쫓겨서라는 변명으로 사오정 서버 개발을 할 때도 Sequelize를 사용하려다가 mysql2로 직접 데이터베이스를 핸들링하기로 했다. 그 과정에서 3개의 테이블을 JOIN해야하는 경우가 생겼는데 이번에 MySQL 일부와 JOIN에 대해서 확실하게 짚고 넘어가자

JOIN

3개의 테이블을 조인을 해야하는 상황이 있었다. 상황은 이렇다.

  1. Client에서 전송한 document_id 와 일치하는 board_contents 조회
  2. 1에서 조회한 row의 board_category와 boards.board_id가 일치하는 boards 조회
  3. 1에서 조회한 row의 member_id와 users.member_id가 일치하는 users 조회
  4. 1,2,3에서 조회한 테이블들을 모두 LEFT JOIN
  5. LEFT JOIN한 테이블들에서 원하는 column만 추출

근데 LEFT JOIN이 뭐지?

왼쪽에 해당하는 테이블은 무조건 표시하고 오른쪽에는 조건에 일치하는 값만 가져온다. 이번에 마주한 상황에서는 board_contents 를 LEFT TABLE로 설정하고 RIGHT TABLE은 차례대로 boards, users 테이블로 설정했다.

  • 그 결과 다음 쿼리를 작성할 수 있었다.
SELECT 
      c.document_id, 
      c.title, 
      c.content, 
      DATE_FORMAT(c.created_at, '%m.%d %H:%i') AS created_at, 
      b.name AS category, 
      u.nickname AS author
FROM `board_contents` AS `c` 
INNER JOIN `boards` AS `b` ON c.board_category = b.board_id 
INNER JOIN `users` AS `u` ON c.member_id = u.member_id 
WHERE c.document_id = ?
  • 쿼리의 결과는 다음과 같다. (NodeJS mysql2 패키지 createPool().query() 기준)
{
    "document_id": :documentId,
    "title": "TEST01",
    "content": "TEST0001",
    "created_at": "07.26 09:25",
    "category": "공지사항"
    "author": "Intelligent Metal Sausages"
}

기타 유용한 MySQL 함수들

DATE_FORMAT(DATE, FORMAT)

날짜를 지정한 형식으로 출력하는 함수이다. created_at 같은 column에는 INSERT할 때 default 값으로 CURRENT_TIMESTAMP() 를 설정해놓는 경우가 많다. 이 녀석은 이런 형식이 시간값을 리턴한다. 2015-06-25 06:41:39 반면에 Client에서 원하는 시간의 형식은 다를 수 있다. 이때 DATE_FORMAT() 을 사용하자.
이번 경우에는 07.16 09:46 같은 형식으로 변환해야 했다. 따라서 DATE_FORMAT(c.created_at, '%m.%d %H:%i') 같은 쿼리를 작성했다. 그런데 이렇게 작성하면 JSON에 key 값이 원하는 값이 들어가지 않는다. 따라서 DATE_FORMAT(c.created_at, '%m.%d %H:%i') AS {원하는 이름} 으로 작성하자

형식구분기호 참고문서

profile
노력하는 자는 즐기는 자를 이길 수 없다

0개의 댓글