쿼리문

조영혜·2022년 10월 19일
0

비등가조인: 비등가조인은 동등 연산자가 아닌 연산자를 포함하는 조인조건.

비등가조인을 생성하여 사원의 급여 등급을 계산하는데, 읍여는 해당 등급의 최저급여와 최고급여 사이에 있어야 함. 
SELECT 
	  e.last_name
    , e.salary
    , j.grade_level
FROM 
WHERE e.salary BETWEEN j.lowest_sal and j.highest_sal ;

이 질의가 실행되면 모든 사원이 정확히 한 번만 표시됨. 다음 두 가지 이유로 사원이 반복 표시 되지 않음.

  • 업무 등급 테이블에 겹치는 등급을 포함하는 행이 없음. 즉 사원의 급여 값은 듭여 등급 테이블의 한 행에 있는 최저 급여와 최고 급여 사이에만 있음.
  • 모든 사원의 급여는 업무 등급 테이블에 의해 제한됨. 즉 LOWEST_SAL의 최저 급여보다 적게 받거나 HIGHEST_SAL열의 최고 급여보다 많이 받는 사원은 없음.

<= >= 등 사용 가능하지만 BETWEEN이 가장 간단.
as 쓴 이유는 성능상의 이유. (테이블 접뒁를 사용하면 열을 찾을 위치를 정확히 알 수 있으므로 성능이 개선됨.)

두 테이블을 조인해서 일치하는 열만 반환하는 조인이 내부조인(INNER JOIN)
투 테이블을 조인해서 내부 조인의 결과와 함께 일치하지 않는 왼쪽(or 오른쪽) 테이블의 행을 반환하는 조인이 왼쪽(or 오른쪽) 포괄조인(OUTER JOIN)
두 테이블을 조인해서 내부 조인의 결과와 함께 왼쪽 및 오른쪽 조인의 결과를 반환하는 조인이 전체포괄조인 (FULL OUTER JOIN)

WHERE 절은 그룹을 제한하는 데 사용할 수 없음. -> HAVING

SELECT
	  department_id
    , AVG(salary) 
FROM employees 
HAVING AVG(salary) > 8000; 

SELECT
	  department_id
    , AVG(salary) 
FROM employees 
WEHRE AVG(salary) > 8000 
GROUP BY department_id; 

Able 보다 급여가 많은 사원을 찾는 질의를 작성한다고 가정합니다.
이 문제를 해결하려면 Able의 급여를 찾는 첫번째 질의와 해당 급여보다 급여가 많은 사원을 찾는 두번째 질의, 즉 두개의 질의가 필요합니다.
이 문제는 두 질의를 결합하여 한 질의를 다른 질의 내부에 포함시키면 해결됩니다.
내부 질의(서브쿼리)는 외부질의(메인쿼리)에 사용될 값을 반환합니다. 서브 쿼리 사용은 두 개의 순차적인 질의를 수행하여 첫번째 질의 결과를 두번째 질의의 검색 값으로 사용하는 것과 동일합니다.

서브쿼리는 다른 SELECT 문의 절에 삽입된 SELECT문으로서 서브쿼리를 사용하면 간단한 명령문으로 강력한 기능을 제공하는 명령문을 작성할 수 있습니다. 서브쿼리는 테이블 자체의 다음과 같은 여러 SQL절에 서브쿼리를 포함 시킬 수 있습니다.

  • WHERE 절
  • HAVING 절
  • FROM 절
    일반적으로 서부쿼리가 먼저 실행되고 그 출력 결과를 사용하여 메일쿼리에 대한 질의 조건을 완성.
  • 비교조건의 오른쪽에 서브쿼리를 넣습니다.
  • 서브쿼리의 ORDER BY절은 TOP-N분석을 수행하지 않을 경우 필요가 없습니다.
  • 단일 행 서브쿼리에는 단일 행 연산자를 사용하고 다중행 서브쿼리에는 다중행 연산자를 사용합니다.

UNION - 두 질의 중 어느 것 하나에 의해서라도 선택된 모든 구분(distinct) 행
UNION ALL - 중복 행을 포함하여 두 질의 중 어느 것 하나에 의해서라도 선택된 모든 행
MINUS - 첫째 SELECT 문에 의해 선택되고 둘째 SELECT 문에 선택되지 않은 모든 구분 행

  • 모든 SET연상자는 동등한 우선순위를 가짐. 우선적으로 순서 지정하려면 괄호 필수.
  • SELECT 하는 필드 수가 같아야 하고 각 필드의 데이터타입이 같아야 함.

INTERSECT - 여러 질의에 공통적인 행을 모두 반환.
MINUS - 첫째 질의가 반환한 행으로부터 둘째 질의가 반환한 행을 제외한 행이 반환. (첫째 SELECT문, MINUS 둘째 SELECT문)

  • 질의에 있는 SELECT문에 의해 선택될 열의 개수와 데이터 유형은 질의에 사용된 모든 SELECT문에서 같아야 함. 열의 이름은 같지 않아도 됨.
  • WHERE절에 있는 모든 열이 SELECT 절에 있어야 MINUS 연산자 작동 가능.
SELECT last_name, salary, department_id 
FROM employees outer 
WHERE salary > 
	( SELECT AVG(salary) 
	  FROM employees 
      WHERE department_id = outer.department_id ) ; 

메인쿼리 : 소속부서의 평균 급여보다 많은 급여를 받는 사원 출력 
서브쿼리 : 각 부서의 평균 급여 계산. 
      
/* 외부 질의와 내부 질의의 FROM절에서 모두 employees 테이블을 사용하므로 확실히 하기 위해 메인 SELECT문의 employees에 별칭 사용. (outer) 
별칭을 사용하면 전체 SELECT문을 읽기 쉬워지며 별칭을 하용하지 않는 경우 서브쿼리문에서 외부 테이블 열과 내부 테이블 열을 구별할 수 없으므로 질의가 제대로 작동하지 않을 수 있음. */ 

업무를 두 번 이상 바꾼 사원에 대한 정보 출력
SELECT e.employee_id, last_name, e.job_id
FROM employees e 
WHERE 2 <= 
	( SELECT COUNT(*) 
      FROM job_history
      WHERE employee_id = e.employee_id ) ; 

1. 메인쿼리에 지정된 테이블에서 행을 선택합니다. 이 행이 현재 후보 행입니다. 
2. 이 후보행의 서브쿼리에서 참조하는 행의 값을 저장합니다. 서브쿼리에서 참조하는 행은 e.employee_id. 
3. 메인쿼리의 후보 행 값을 참조하는 조건을 사용하ㅕㅇ 서브쿼리를 실행합니다. 그룹함수 COUNT(*)가 2단계에서 얻은 e.employee_id 열 값에 대해 계산됩니다. 
4. 3단계에서 수행된 서브 쿼리의 결과를 바탕으로 외부 질의의 WHERE절을 평가합니다. 이 단계가 후보 행의 출력 여부를 결정합니다. 서브쿼리에서 평가된 사원의 업무 변경 횟수를 외부 질의의 WHERE절에서 2와 비교합니다. 조건을 만족하면 해당 사원 레코드가 표시됩니다. 
5. 테이블에 있는 행이 모두 처리될 때까지 다음 후보 행에 대해 같은 과정을 반복합니다. 

상관관계는 서브쿼리에 있는 메인쿼리 질의 요소를 사용하여 성립됩니다. 서브쿼리의 테이블에 있는 employee_id를 메인쿼리 질의의 테이블에 있는 employee_id와 비교 하는 employee_id = e.employee_id문에서 상관관계가 성립됩니다. 

0개의 댓글