VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
mysql -u root -p sakila로 클라이언트를 여세요.
서브쿼리의 동작 방식
COLUMN_LIST를 원하는 열로, TABLE_NAME을 테이블로, COLUMN_NAME을 검사할 열로, AGGREGATE_FUNCTION을 비교 대상 값을 만드는 함수로 바꾸세요.
서버는 서브쿼리를 실행하고, 그 결과를 가져와, 바깥 쿼리에서 사용합니다.
정확히 1개의 행과 1개의 열을 반환하는 괄호 안의 서브쿼리는 스칼라 서브쿼리이고, 값처럼 동작합니다. 아래의 형태가 그것이고, 가장 자주 잘못되는 형태이기도 합니다.
예제
- 적어 둘 수 없는 값 사용하기
가장 긴 영화의 길이를 모르므로, 그 자리에서 요청합니다.
MAX(length)만으로는 185 외에는 아무것도 주지 않습니다. 서브쿼리가 그것을 WHERE에 다시 넣어 주므로 영화도 함께 얻습니다.
- SELECT 목록의 서브쿼리
같은 값을 SELECT 목록에 넣을 수도 있고, 거기서는 모든 행에 반복됩니다.
- 목록을 반환하는 서브쿼리
IN에 공급하는 서브쿼리는 많은 행을 반환해도 되는데, IN은 값이 아니라 목록을 기대하기 때문입니다.
IN은 각 배우를 그 목록 전체와 대조합니다.
ERROR 1242는 서브쿼리가 너무 많은 행을 반환했다는 뜻입니다
=는 1개의 것을 1개의 것과 비교합니다. 1,000개의 행을 반환하는 서브쿼리를 주면 서버는 더 진행할 수 없습니다.
- 목록을 원했다면
=대신IN을 쓰세요. - 집합에서 1개의 값을 원했다면
MAX()같은 집계를 추가하세요. - 아무 행 1개면 되고
ORDER BY로 어떤 행인지 말할 수 있다면LIMIT 1을 추가하세요.
ERROR 1242는 적어도 소리 내어 실패합니다. 이 실수의 조용한 버전은 서브쿼리가 행을 하나도 반환하지 않는 것입니다: 그러면 NULL이 나오고, 비교도 NULL이 되며, 바깥 쿼리는 아무 말 없이 아무것도 반환하지 않습니다.
요약
- 한 쿼리의 답을 다른 쿼리에 공급하려면 서브쿼리를 쓰세요.
- 1개의 행과 1개의 열을 반환하는 스칼라 서브쿼리는 값처럼 동작한다고 예상하세요.
ERROR 1242는 많은 행을 반환한 서브쿼리에=를 쓴 것으로 읽으세요.- 서브쿼리가 목록을 반환할 때는
=대신IN을 쓰세요. - 바깥 쿼리가 오류 없이 아무것도 반환하지 않으면 빈 서브쿼리를 의심하세요.
함께 보기
- 상관 서브쿼리 — 바깥 행을 읽는 서브쿼리
- IN — 서브쿼리에서 목록을 받는 연산자
- 파생 테이블 — 테이블로 쓰이는 서브쿼리
- MySQL의 서브쿼리 대 JOIN — 어떤 형태를 고를지, 그리고 각각의 비용