SQL join

가연·2024년 12월 30일

cross join

기준 중심 양 쪽 테이블
select * from A cross join B;
or
select * from A,B;

inner join

두 테이블에서 공통 정보로 연결시키기
연결 기준 : on ~
select * from Aaa inner join Bbb on Aaa.id=Bbb.id;
-> 중복되기 때문에 테이블 명 지정 (Aaa -> A, Bbb -> B)
select * from Aaa A inner join Bbb B on A.id=B.id;
inner join 앞의 테이블(A)이 기준 테이블, 뒤 테이블(B)이 참조할 테이블
원하는 컬럼만 보고 싶다면 테이블 별로 컬럼 선택하여 지정. 소속 명시 필요! (A.컬럼)
select A.id, B.name from Aaa A inner join Bbb B on A.id=B.id;

left/right join

한 쪽의 테이블을 기준으로 다른 테이블 참조.
기준 테이블 값이 참조 테이블에 존재할 때만 정보 사용(기준 테이블 값들은 누락 X, 참조 테이블만 누락)
1:1 에 주로 사용. 1:N의 경우 데이터 수가 증가할 수 있어 유의
select * from movies M left join members ME on M.id = ME.movie_id;
=> movie table 기준으로 members 값 가져오기


case when

조건에 따라 값을 구별해 이름 붙일 때
case by case 로 기존의 값에 새로운 값 부여

순차적으로 해결하는 과정에서 새롭게 만든 값을 바탕으로 다시 select 할 때, from에 있는 실존하는 필드들로 표현 해야함 (아닐 경우 에러)
-> 처리 수식/과정을 그대로 작성 (from 필드 값 이용) : sum(B.price*B.amount)
or
-> from 뒤에 중첩문으로 실존하도록 만들기 : select ~~ from (중첩 ..)A ~~; 별칭 필요!

ex/

select U.userID, U.name, 
	sum(B.price*B.amount) as `TotalPrice`,
    case when (sum(B.price*B.amount) >=1500) then "VVIP"
		 when (sum(B.price*B.amount) >=1000) then "VIP"
         when (sum(B.price*B.amount) >=1) then "Basic"
         else "Ghost" 
	end as `CustomerClass`
		from buytbl B right join usertbl U
				on B.userID=U.userID
			group by U.userID
			order by `TotalPrice` desc;

or

select U.userID, sum(B.price*B.amount) as `TotalPrice` 
		from buytbl B right join usertbl U
				on B.userID=U.userID
			group by U.userID
			order by `TotalPrice` desc;
#위의 내용을 중첩시키기
            
select *, case when (TotalPrice>=1500) then "VVIP"
			   when (TotalPrice>=1000) then "VIP"
               when (TotalPrice>=1)    then "Basic"
			   else "Ghost"
		  end as `CustomerClass` from (select U.userID, sum(B.price*B.amount) as `TotalPrice` 
		from buytbl B right join usertbl U
				on B.userID=U.userID
			group by U.userID
			order by `TotalPrice` desc)A;

자주 사용되는 문법들 정리

# 유니크한 값 : distinct or groupby 이용
select distinct U.userID, U.name, U.addr, B.prodname from buytbl B inner join usertbl U on B.userID=U.userID group by U.userID;

# 카운팅 : count(*) or count(1) or count(PK/특정컬럼)
select userID, count(userID) from buytbl group by userID;
#조건 걸기
select userID, count(num) from buytbl where groupname = '전자' group by userID ;
select userID, count(num) from buytbl where groupname = '전자' group by userID having count(num) >= 2 ;
# 조건을 2개 걸고 싶을 때! when+having! when은 무조건 from 뒤에, 처리된 값 필터링은 having - groupby 뒤에

# where + 특수 조건 : between, like ... etc
select * from usertbl where birthYear between 1970 and 1980;
select * from usertbl where userID like '%k%' ;

# case when ~~ end : 조건에 따라 값 바꾸기, 카운팅, 비율 계산 
# 세대 별로 나누기, **년대 값 할당 
select userID , name, case when birthyear between 1950 and 1959 then '50년대'
						 when birthyear between 1960 and 1969 then '60년대'
                         when birthyear between 1970 and 1979 then '70년대'
                         when birthyear between 1980 and 1989 then '80년대'
                         else '기타세대'
				end as `세대`
 from usertbl;
 # 위의 세대 카운팅(count, group by), 그 수 조건까지(having)
 select userID , name, case when birthyear between 1950 and 1959 then '50년대'
						 when birthyear between 1960 and 1969 then '60년대'
                         when birthyear between 1970 and 1979 then '70년대'
                         when birthyear between 1980 and 1989 then '80년대'
                         else '기타세대'
				end as `세대`, count(1) as `명수`
 from usertbl group by `세대` having `명수` >= 3;
 
# 값 재구성 + 분포
select addr, case when addr in ("서울","경기") then "수도권"
				when addr in ("경북", "경남") then "경상도"
                else "기타권역"
			end as `권역별`, count(1) as `명수`
		from usertbl group by `권역별`;
# **특정한 조건 카운팅 - case when 사용 : 관심있는 조건은 1로, 그 외 0으로 값 바꿔서 합 구하기
select sum(case when addr='서울' then 1 else 0 end) as `서울여부` from usertbl;


# 서브 쿼리
# 1. 조건 식에 들어갈 때 : 조건 기준 값이 데이터 값에 종속될 때, 데이터 값을 쿼리문으로 요청
# 2. from 자리에 들어갈 때 : 찾고자 하는 데이터에 조건(필터링) 걸기, 별칭 필요!!
#						 select ~~ from (select ~~)A; # 별칭 A
#						 select ~~ from (select ~~ from ~~ ) -> error

0개의 댓글