본문 바로가기

외부 활동/UMC 2기 서버[NODE]

5주차 - aquerytool 사용하여 erd설계 및 데이터베이스 쿼리 실습

 

 

 

이후 위 과정으로 생성한 erd를 rds에 생성을 해보자 !

원래 FK연결을 해주어야 하지만 난 무료 버전이라 대충 sql문만 따오는 용도로 만듬.

근데 궁금한게 FK연결을 따로 안해줘도 sql문 상에는 차이가 없는데 왜 그런건지 모르겠다.

그저 연결관계만 보여주는게 끝인건가..?

 

 

데이터 베이스를 생성 안하고 erd를rds에 생성하려고 하자 오류가 나서 데이트베이스를 생성을 다시 sql을 넣어줌

 

음 트리플 모니터를 쓰다 보니 카톡 내용이 들어가버렸네 영상 편집 공부 하고 와서 수정 할 예정쓰

 

 

퀴리문 실습은 사진과 코드가 날아가서 같은 조 인 슈리의 노션을 참고 하였다.

 

쿼리문의 경우 기본적으로 SELECT, FROM, WHERE로 구성된다.

  • SELECT : 원하는 요소를 가져온다.
  • FROM : 가져오는 테이블을 지칭한다.
  • WHERE : 쿼리문에서의 조건이라 생각하면 편하다.

SELECT name,nickName

FROM User

WHERE userIdx=3;

User테이블에서 name과 nickName을 가져오게 된다.

 

 

 

 

SELECT COUNT(postIdx) FROM Post WHERE status='ACTIVE' and userIdx=2;

Post에서 활성화 상태이면서, userIdx가 2번인 사람의 postIdx를 구하는 것이다

 

 

 

그러면 다음과 같이 postIdx가 2와 3이 반환되는데, 반환되는 postIdx의 갯수를 COUNT함수를 이용하여 센다.

 

이제 join함수를 사용해보자.

 

SELECT name, nickName, profileImgUrl, Post.postIdx

FROM User join Post on Post.userIdx = User.userIdx and Post.status='ACTIVE'

WHERE User.status='ACTIVE' and User.userIdx=2;

 

가장 중요한 것은 FROM 과 WHERE 에서 다른 테이블을 연결하는 과정이기에, 인자 이름이 겹쳐질 수도 있다.

따라서 이를 방지하기위해 객체와 같은 방법을 사용한다.

 

 

SELECT name, nickName , profileImgUrl , postIdx

FROM User

           join (SELECT postIdx, userIdx

           FROM Post

           WHERE status='ACTIVE') p on p.userIdx=User.userIdx

WHERE User.status='ACTIVE' and User.userIdx=2;

 

과 같이 사용할 수 있다.

join의 안쪽을 자세히 보면, Post에서 ACTIVE인 상태의 postIdx와 userIdx을 가져온다. 그리고 이를 p라고 지칭한다. 이후 p.userIdx와 User.userIdx가 같은 경우를 모두 표시한다.

 

 

 

그런데 다음과 같은경우는 정상적으로 출력되지 않는다.

SELECT name, nickName , profileImgUrl , CountPost

FROM User

          left join (SELECT COUNT(postIdx) as CountPost, userIdx

          FROM Post

          WHERE status='ACTIVE') p on p.userIdx=User.userIdx

WHERE User.status='ACTIVE' and User.userIdx=2;

 

 

 

SELECT COUNT(postIdx) as CountPost, userIdx

          FROM Post

          WHERE status='ACTIVE'

SELECT COUNT(postIdx) as CountPost, userIdx           FROM Post           WHERE status='ACTIVE'

위의 서브 퀴리만 실행 하였을때의 결과이다.

 

 

 

그 이유는 join에서 p에 제일 처음 담기는 p.userIdx는 1이고 User.userIdx는 2이다. ==> 이거 왜인지 모르겠음

그런데 1과 2는 같지 않으므로, postIdx에는 아무것도 담기지 않아 Null값으로 표시 되는것이다.

정상적으로 작동되기 위해서 p.userIdx가 1과, 2까지도 비교를 해주어야 한다.

이를 해결해주기 위해 group by를 사용하여 userIdx을 기준으로 각각의 userIdx가 1일때와 2일때를 둘다 계산해준다.

 

 

IF(CountPost is null, 0, CountPost)as CountnPost==>F문을 사용하여 CountPost가 null일 경우 0으로 바꾸어준다.

 

SELECT User.userIdx,

               name,

              nickName,

              profileImgUrl,

              IF(CountPost is null, 0, CountPost) as CounntPost,

              IF(FollowerCount is null, 0, FollowerCount) as FollowerCount,

              IF(FolloweeCount is null, 0, FOlloweeCount) as FolloweeCount

 

FROM User

              left join (SELECT COUNT(postIdx) as CountPost, userIdx

                            FROM Post

                            WHERE status = 'ACTIVE'

                            group by userIdx) p on p.userIdx = User.userIdx

 

              left join (SELECT COUNT(followerIdx) as FollowerCount, followeeIdx

                            FROM Follow

                            WHERE status = 'ACTIVE'

                            group by followeeIdx) fwer on fwer.followeeIdx = User.userIdx

 

              left join (SELECT COUNT(followeeIdx) as FolloweeCount, followerIdx

                            FROM Follow

                            WHERE status = 'ACTIVE'

                            group by followerIdx) fwee on fwee.followerIdx = User.userIdx

WHERE User.status = 'ACTIVE' and User.userIdx = 1;

 

자 그러면 left join을 join으로 바꾸면 어떻게 될까?

join은 데이터 값이 없을때 처리하지 않고, left join의 경우 데이터 값이 없을 때 null로 처리한다. 지금과 같은 경우에 데이터가 없을때 null로 처리를 진행해야 해서 left join을 사용해야 한다.

 

 

 

 

실습은 패쓰