SQL/Sqlite

SQLite 6. 서브쿼리

컴닥 2021. 12. 30. 14:09
반응형
SELECT *
FROM mlb_players
WHERE "Weight(lbs)">240​

AND 조건문을 서브 쿼리로 바꿔 보았다.

SELECT *
FROM (
	SELECT *
	FROM mlb_players
	WHERE "Weight(lbs)">240
    )
WHERE Position='First Baseman'

(다음) 내부의 쿼리가 먼저 실행되고, 그 결과(테이블)가 외부의 쿼리 문으로 전달된다. 

SELECT *
FROM mlb_players
WHERE Position='First Baseman' AND "Weight(lbs)">240

 

속도 느려지고, 구문 복잡하고 별 메리트가 없어 보이는 게 사실이나...

여러 테이블을 넘나 들며 쿼리를 작성해야 할 때는 꽤 유용하게 쓰인다. 

 

원래 실습 데이터에는 테이블이 하나 밖에 없어서
기존 실습 데이터를 수정했다. 

test2.zip
0.03MB

 

체중은 계속 변할 수도 있으니
변화하는 체중을 기록할 수 있도록
별도의 테이블로 분리하고 측정일 컬럼을 만들어 두었다. 
일종의 제1정규화(normalization)라고도 할 수 있다. 

(실습을 위해 가상의 측정일을 넣었으며,
가상의 측정 데이터도 하나 추가해 두었다.)

정규화에 대해 궁금한 점이 있다면
다음 링크들을 참고하자. 
https://mangkyu.tistory.com/110 
https://itwiki.kr/w/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4_%EC%A0%95%EA%B7%9C%ED%99%94

'데이터의 중복(저장)을 하지 말자'는 원칙을 꼭 기억하자. 
제3정규화까지는 보편적으로 사용된다. 
낮은 단계의 정규화는 이해해야 JOIN을 이해할 수 있다. 

 

체중 측정 횟수가 1이 아닌 선수를 찾아보자. 

SELECT * 
FROM players
WHERE id IN (
	SELECT id 
	FROM weights
	GROUP BY id
	HAVING count(weight) <> 1
)

641번은 체중이 NULL인 선수고
120번은 2회 측정(가공의 측정값을 하나 더 추가)한 선수다. 

* WHERE IN 구문에 서브 쿼리가 많이 사용된다. 

선수들의 체중 측정 횟수를 알아보자. 

(편의상 측정 횟수가 1회가 아닌 2명의 결과만 확인하자.)

SELECT id, name, (
	SELECT count(weight)
	FROM weights
	WHERE weights.id = players.id
) AS CNT
FROM players
WHERE id IN (120, 641)

컬럼명이 겹치는 경우
table_name.column_name으로
어느 테이블에 속한 컬럼인지 명시해주어야 한다. 

반응형