Mysql&DBeaver

DBeaver)SELECT 안에 SELECT 또 쓸 수 있음 (서브쿼리)

연습노트 2024. 9. 6. 13:12

실은 SELECT 문법안에 SELECT 이런걸 또 사용할 수 있습니다. 

서브쿼리라고 하는데 언제 어떻게 쓰는지 알아봅시다. 

 

 

 

 

 

 

Q. 위의 card테이블에서 "사용금액들의 평균"보다 더 큰 사용금액을 가진 사람만 출력하고 싶으면 어떻게하죠? 

 

1. 사용금액의 평균을 구해서 

2. 사용금액 > 평균인 행만 출력해주쇼

라고 코드짜면 되는거 아닙니까 

 

 

 

 

SELECT AVG(사용금액) FROM card 

1. 컬럼에 있는 값을 평균내고 싶으면 AVG() 쓰면 된다고 했습니다.

그걸 써서 평균을 구합니다. 대충 245000원이 나옵니다.

 

 

SELECT * FROM card WHERE 사용금액 > 245000

2. 그 다음에 평균 245000보다 높은 것들만 출력하라고 조건문 쓰면 됩니다.  

근데 이걸 수동으로 2번 입력하는건 너무 귀찮지 않습니까?

그럼 하나로 합치면 됩니다. 

 

 

 

SELECT * FROM card WHERE 사용금액 > 
  (SELECT AVG(사용금액) FROM card)

SELECT 쿼리안에 다른 SELECT 쿼리를 자유롭게 넣을 수 있습니다.

저렇게 다른 쿼리 안에 들어가는 쿼리를 서브쿼리라고 합니다. 

 

그럼 소괄호에 있는 쿼리먼저 실행하고 결과를 뱉고 다음 쿼리를 실행해줍니다. 

그래서 위 코드는 소괄호 안에 있는 SELECT 어쩌구가 먼저 실행되어 평균값 245000 을 그 자리에 남겨줄거고

그 다음에 사용금액 > 245000 인 행만 출력해줄듯요.  

 

(참고)

- 문자나 숫자 들어갈 곳에 서브쿼리를 대신 넣을 수 있습니다.

- 그래서 1개의 문자나 숫자를 뱉는 SELECT문만 서브쿼리로 넣을 수 있음 

(여러개의 행을 뱉는 SELECT는 서브쿼리 역할을 할 수 없습니다)

- 서브쿼리 넣을 때 ( ) 소괄호 까먹으면 안됩니다. 

 

 

 

 

 

서브쿼리는 어려운거 아니고 

님들이 쿼리 2개를 각각 실행해야하는 상황이 있을 때 

각각 실행하기 귀찮으면 저렇게 합칠 수 있도록 도와주는 문법일 뿐입니다. 

서브쿼리 싫으면 2번 각각 실행해서 쓰십쇼

 

 

 

 

 

컬럼명자리에 서브쿼리를 넣어보자

 

컬럼명에 사칙연산할 수 있다고 했는데 

그래서 사칙연산할 때도 서브쿼리 같은거 넣을 수 있습니다. 

 

SELECT 사용금액 / 245000 FROM card 

이렇게 평균금액으로 나눈 값을 구하고 싶으면 

 

SELECT 사용금액 / (평균금액구하는 SELECT 문법) FROM card 

이렇게 써도 된다는 소리입니다. 

 

 

 

 

 

SELECT 고객명, '메렁' FROM card 

그리고 여러분들 컬럼명 자리에 숫자나 문자 넣으면 그거 그대로 출력해주는거 아십니까

위처럼 코드짜서 실행해보면 

 

 

 

▲ 넣은 문자가 그대로 출력됩니다. 

 

 

그렇다면 컬럼명 넣는 자리에 숫자나 문자 대신 괄호치고 서브쿼리넣어도 되는 것이 아닐까요?

됩니다.

 

SELECT 고객명, (SELECT AVG(사용금액) FROM card) FROM card; 

이렇게 서브쿼리는 아무데나 사용가능합니다. 

쓸데는 없어보이는데 아무튼 이런 것도 가능하다는걸 신나게 보여주고 싶었을 뿐입니다. 

 

 

 

 

 

 

 

IN( ) 안에 서브쿼리를 넣어보자

 

카드회사는 카드값 안값는 나쁜 놈들을 따로 보관해둡니다.

우리도 테이블을 새로 하나 만들어서 나쁜 회원 목록을 블랙리스트로 만들어 보관해봅시다.

 

 

 

▲ blacklist라는 테이블을 만들고

VARCHAR(100) 컬럼하나 만들어서 이름 3개를 보관해봤습니다. 

똑같이 만들어봅시다. 

 

 

 

Q. card 테이블에서 블랙리스트 회원들의 사용금액을 출력하려면 어떻게 코드를 짜야하죠?

 

쉬운건 알아서 합시다

 

SELECT 사용금액 FROM card 
WHERE 고객명 IN ('Pristine', 'George', 'Amy') 

당연히 WHERE 문법 잘 쓰면 조회가능합니다. 

 

[collapse]

 

 

 

 

 

 

 

 

 

 

 

SELECT 사용금액 FROM card
WHERE 고객명 IN ('Pristine', 'George', 'Amy')

SELECT 사용금액 FROM card 
WHERE 고객명 IN (SELECT 이름 FROM blacklist) 

실은 IN () 안에 문자나 숫자가 여러개 넣을 수 있는데

그 자리에 서브쿼리를 넣을 수도 있습니다. 

그래서 위 2개 코드는 똑같은 결과가 출력됩니다. 

 

그럼 서브쿼리가 먼저 실행되어서 'Pristine', 'George', 'Amy' 이런 값들을 가져오고

WHERE 고객명 IN ('Pristine', 'George', 'Amy') 이걸 연산해주겠군요. 

 

 

 

Q. 뭐여 문자나 숫자를 1개만 뱉는 SELECT문만 서브쿼리역할을 할 수 있다면서요 

- IN() 안에선 예외임 ㅅㄱ

 

 

 

 

 

 

 

오늘의 결론은 

여러 SELECT 문장을 서브쿼리 형태로 하나로 합칠 수 있습니다.

편해보이면 그렇게 사용하면 됩니다. 

 

심지어 위의 예제 잘 보면 다른 테이블을 SELECT한 결과도 서브쿼리로 넣을 수 있음을 알 수 있는데 

테이블을 2개 이상 사용해서 결과를 뽑을 땐 대부분 서브쿼리말고 나중에 배울 JOIN 문법을 사용합니다. 

그래도 대부분 동일한 결과를 얻을 수 있고 처리속도도 더 빠르고 문법도 약간 더 이해가 쉽습니다. 

 

 

 

 

 

 

Q1. "고객등급이 패밀리인 사람들의 평균 연체횟수"보다 연체횟수가 높은 사람은 몇명일까요?

SELECT 어쩌구 쿼리가 2번 필요할 수 있습니다. 심심하면 하나로 합쳐보십쇼 

SELECT AVG(연체횟수) FROM card WHERE 고객등급 = '패밀리'

패밀리인 사람들의 평균 연체횟수를 구했더니 대충 6.25가 나옵니다.

 

 

SELECT COUNT(*) FROM card WHERE 연체횟수 > 6.25 

그거보다 높은 사람을 세어봤습니다. 3명이 나오네요 끝

 

 

SELECT COUNT(*) FROM card WHERE 연체횟수 > 
  (SELECT AVG(연체횟수) FROM card WHERE 고객등급 = '패밀리') 

귀찮게 쿼리를 2번 작성하기 싫으면 쿼리 2개를 합치면 됩니다.

숫자나 문자들어갈 곳에 괄호치고 SELECT 쿼리 작성할 수 있습니다. 

 

[collapse]

 

 

 

 

Q2. 위 사진처럼 개인의 사용금액이 평균사용금액과 얼마나 차이가 나는지 출력해봅시다.

어려우면 SELECT 2줄 쓰면 되는것이지 뭘 고민

 

우선 사용금액의 평균을 구해봅시다. 

 

 

SELECT AVG(사용금액) FROM card 

해보면 24만5천원 어쩌구가 나옵니다. 

이제 그걸 가지고 계산해보면 되겠군요 

 

 

 

SELECT 고객명, 사용금액, 사용금액 - 245000 AS DIFF FROM card; 

이러면 의도대로 결과가 잘 출력됩니다. 

하지만 SELECT 2개를 합쳐서 쓰고 싶으면 

 

 

SELECT 고객명, 사용금액, 사용금액 - (SELECT AVG(사용금액) FROM card) AS DIFF FROM card; 

이러면 되겠군요

그냥 소괄호 열고 다른 SELECT 집어넣어주면 됩니다.

 

긴 코드부터 읽고 이해하려고 하면 어렵습니다.

그래서 뭐라도 직접 해봐야지 답보고 따라적는건 별 의미없습니다.