SQL의 중첩 쿼리

SQL 언어를 사용하면 하나의 쿼리를 다른 쿼리 내에 중첩할 수 있습니다. 이렇게 하면 코드의 가독성이 크게 떨어지더라도 크고 복잡한 작업을 수행하는 하나의 매우 큰 쿼리를 작성할 수 있습니다.

서브쿼리가 반환하는 값의 개수에 따라 적용할 수 있는 영역이 달라진다. 총 세 가지 옵션이 있습니다.

  • 하위 쿼리는 하나의 단일 값 (하나의 열과 하나의 행)을 반환합니다.
  • 하위 쿼리는 값 목록 (하나의 열이 있는 테이블)을 반환합니다.
  • 하위 쿼리는 테이블 (많은 열, 여러 행)을 반환합니다.

각 경우에 대해 하나의 예를 살펴보겠습니다.

스칼라 결과가 포함된 하위 쿼리

급여가 회사 평균보다 높은 직원 테이블에서 모든 직원 목록을 찾아봅시다. 어떻게 할 수 있습니까?

미리 알면 직원의 급여를 평균과 비교하여 직원을 쉽게 필터링할 수 있습니다. 동시에 회사 직원의 평균 급여를 계산할 수 있는 쿼리를 이미 작성했습니다. 기억합시다:

SELECT AVG(salary) FROM employee 

그런 다음 MySQL은 76833.3333 값을 반환했습니다 .

급여가 평균 이상인 모든 직원의 목록을 찾는 방법은 무엇입니까? 또한 매우 간단합니다.

 SELECT * FROM employee 
   WHERE salary > 76833.3333 

이 쿼리의 결과는 다음과 같습니다.

ID 이름 직업 샐러리
1 이바노프 이반 프로그램 제작자 100000
2 페트로프 페트르 프로그램 제작자 80000
4 라비노비치 모이샤 감독 200000

이제 값 76833 대신 첫 번째 요청을 대체하여 두 요청을 결합합니다.

   SELECT * FROM employee 
   WHERE salary > (SELECT AVG(salary) FROM employee) 

이 쿼리의 결과는 동일합니다.

ID 이름 직업 샐러리
1 이바노프 이반 프로그램 제작자 100000
2 페트로프 페트르 프로그램 제작자 80000
4 라비노비치 모이샤 감독 200000

값 목록이 포함된 하위 쿼리

한 테이블에서 다른 테이블의 해당 레코드가 없는 모든 레코드를 찾는 작업을 한 번 기억하십니까?

이런 사진도 있었습니다.

내가 착각하지 않았다면 작업은 다음과 같습니다. 작업 테이블에 작업이 없는 직원 테이블의 모든 직원 목록 표시 .

두 단계로 해결책을 찾아봅시다.

먼저 작업 테이블에 작업이 있는 모든 직원의 ID를 반환하는 쿼리를 작성해 보겠습니다. 두 가지만 기억하세요.

  • 중복 제거 - DISTINCT 키워드를 사용하십시오.
  • 결과에서 NULL 값을 제거합니다.
SELECT DISTINCT employee_id FROM task 
   WHERE employee_id IS NOT NULL

그리고 여기 우리는 그러한 요청에 대한 아름다운 결과를 얻었습니다.

employee_id
1
2
5
4
6

편의를 위해 일시적으로 1,2,5,4,6의 순서로 적어둡니다. 이제 첫 번째 목록에 포함되지 않은 ID를 가진 직원 목록을 반환하는 직원 테이블에 대한 두 번째 쿼리를 작성해 보겠습니다.

SELECT * FROM employee  
WHERE id NOT IN (1,2,5,4,6)

그리고 이 쿼리의 결과는 다음과 같습니다.

ID 이름 직업 샐러리 나이 가입 날짜
이바노프 세르게이 시험 장치 40000 서른 2014-01-01

이제 앞의 예에서와 같이 id 목록 대신 첫 번째 요청의 본문을 간단히 대체하여 두 요청을 결합할 수 있습니다.

 SELECT * FROM employee 
   WHERE id NOT IN ( 
      	SELECT DISTINCT employee_id FROM task 
      	WHERE employee_id IS NOT NULL 
   )