개발자였던 것/데이터베이스

신입 기술 면접 예상 질문 & 코딩 테스트

서으이 2020. 11. 17. 12:28
728x90
반응형

서브 쿼리

  • 하나의 SQL문 안에 포함되어 있는 또 다른 SQL.
  • 서브 쿼리는 알려지지 ㅇ낳은 기준을 이용한 검색을 위해 사용한다.
  • 서브 쿼리는 메인쿼리가 서브쿼리를 포함하는 종속적인 관계이다.

서브쿼리 사용 시 주의사항

  • 서브 쿼리를 괄호로 감싸서 사용한다.
  • 서브 쿼리는 단일 행(Single Row) 또는 복수 행(Multiple Row) 비교 연산자와 함께 사용 가능하다. 단일 행 비교 연산자는 서브 쿼리의 결과가 반드시 1건 이하이어야 하고 복수 행 비교 연산자는 서브쿼리의 결과 건수와 상관없다.
  • 서브 쿼리에서는 ORDER BY를 사용하지 못한다. ORDER BY절은 SELECT절에서 오직 한 개만 올 수 있기 때문에 ORDER BY절은 메인쿼리의 마지막 문장에 위치해야 한다.

 

1. 단일행 서브쿼리

  • 서브 쿼리의 실행 결과가 항상 1건 이해인 서브 쿼리를 의미한다.
  • 단일행 서브 쿼리는 단일 행 비교 연산자와 함께 사용된다.
  • 단일 행 비교 연산자는 =, <, <=, >=, <>이 있다.

[예제] 정남일 선수의 소속팀을 알아내는 SQL문(서브 쿼리 부분)과 이 결과를 이용해서 해당 팀에 소속된 선수들의 정보를 출력하는 SQL문(메인쿼리 부분)으로 구성된다. 정남일 선수가 소속된 팀의 선수들에 대한 정보를 표시하는 문제를 서브쿼리 방식의 SQL문으로 작성하면 다음과 같다.

1
2
3
4
5
6
SELECT PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버 
FROM PLAYER
WHERE TEAM_ID = (SELECT TEAM_ID
                FROM   PLAYER
                WHERE  PLAYER_NAME = '정남일')
ORDER BY PLAYER_NAME;
cs

 

[예제] 선수들의 평균 키를 알아내어 평균 키보다 작거나 같은 선수들을 출력

1
2
3
4
5
SELECT PLAYER_NAME 선수명, POSITION 표지션, BACK_NO 백넘버
FROM PLAYER
WHERE HEIGHT <= (SELECT AVG(HEIGHT)
                FROM PLAYER)
ORDER BY PLAYER_NAME;
cs

 

2. 다중행 서브 쿼리

  • 서브 쿼리의 실행 결과가 여러 건인 서브 쿼리를 의미한다.
  • 다중행 서브 쿼리는 다중행 비교 연산자와 함께 사용된다.
  • 다중행 비교 연산자에는 IN, ALL, ANY, SOME, EXISTS가 있다. 그렇지 않으면 SQL문은 오류를 반환한다.

[예제] 선수들 중에서 ‘정현수’라는 선수가 소속되어 있는 팀 정보를 출력

1
2
3
4
5
6
SELECT REGION_NAME 연고지명, TEAM_NAME 팀명, E_TEAM_NAME 영문팀명
FROM TEAM
WHERE TEAM_ID IN (SELECT TEAM_ID 
                  FROM PLAYER
                  WHERE PLAYER_NAME = '정현수')
ORDER BY TEAM_NAME;
cs

 

3. 다중 칼럼 서브 쿼리

  • 서브 쿼리의 실행결과로 여러 칼럼을 반환한다.
  • 메인 쿼리의 조건절에 여러 칼럼을 동시에 비교할 수 있다.
  • 서브 쿼리와 메인 쿼리에서 비교하고자 하는 칼럼 개수와 컬럼의 위치가 동일해야 한다.
  • 다중 컬럼 서브 쿼리는 서브 쿼리의 결과로 여러 개의 칼럼의 반환되어 메인 쿼리의 조건과 동일시에 비교되는 것을 의미한다.

[예제] 소속팀별 키가 가장 작은 사람들의 정보를 출력

1
2
3
4
5
6
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE (TEAM_ID, HEIGHT) IN (SELECT TEAM_ID, MIN(HEIGHT) 
                            FROM PLAYER GROUP 
                            BY TEAM_ID)
ORDER BY TEAM_ID, PLAYER_NAME;
cs

 


조인(Join)

  • 둘 이상의 테이블을 연결하여 데이터를 검색하는 방법이다.
  • 보통 둘 이상의 행들의 공통된 값 Primary Key 및 Foreign Key 값을 사용하여 조인한다.
  • 두 개의 테이블을 SELECT문장 안에서 조인하려면 적어도 하나의 칼럼이 그 두 테이블 사이에서 공유되어야 한다.

 

1.Inner Join

  • 가장 일반적인 형태의 조인을 내부 조인(Inner Join)이라고 한다. 
  • 서로 매칭 되는 것만 엮어 조회한다. 즉 두 개의 집합 (A, B)의 교집합이라고 이해하면 된다.
  • 테이블 간의 공통 칼럼을 사용하여 칼럼 값이 같은 데이터들을 연결한 조인 방법을 말한다.

[그림 Ⅱ-1-12]는 선수와 팀, 팀과 운동장 테이블 간의 관계를 설명한 것이다. 

[예제] 세 개의 테이블에 대한 JOIN을 구현해 보도록 한다. 선수들 별로 홈그라운드 경기장이 어디인지를 출력하고 싶다고 했을 때, 선수 테이블과 운동장 테이블이 서로 관계가 없으므로 중간에 팀 테이블이라는 서로 연관관계가 있는 테이블을 추가해서 세 개의 테이블을 JOIN 해야만 원하는 데이터를 얻을 수 있다.

 

// INNER JOIN은 INNER 키워드를 생략 가능

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션,
        T.REGION_NAME 연고지, T.TEAM_NAME 팀명,
        S.STADIUM_NAME 구장명
FROM PLAYER P, TEAM T, STADIUM S
WHERE P.TEAM_ID = T.TEAM_ID
AND T.STADIUM_ID = S.STADIUM_ID
ORDER BY 선수명;
 
//또는 INNER JOIN을 명시하여 사용할 수도 있다.  
SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션,
        T.REGION_NAME 연고지, T.TEAM_NAME 팀명,
        S.STADIUM_NAME 구장명
FROM PLAYER P INNER JOIN TEAM T
ON P.TEAM_ID = T.TEAM_ID
    INNER JOIN STADIUM S
ON T.STADIUM_ID = S.STADIUM_ID
ORDER BY 선수명;
cs

 

2. Outer Join

  •  매칭뿐만 아니라 미매칭 데이터도 함께 조회한다.
  • 동일 조건에서 조인 조건을 만족하는 값이 없는 행들을 조회하기 위해 외부(Outer Join)를 사용한다.
  • Outer Join 연산자는 "(+)"이다.
  • 조인 시 값이 없는 조인 측에 "(+)"를 위치시킨다.
  • Outer Join 연산자는 표현식의 한 편에만 올 수 있다.

[예제] 부서 번호를 조회하는 예제

1
2
3
SELECT DISTINCT(e.deptno), d.deptno
FROM emp e, dept d
WHERE e.deptno(+= d.deptno;
cs

[결과] DEPTNO  DEPTNO
        ------- --------
             10       10
             20       20
             30       30
                       40

 

Outer Join을 사용하는 테이블에 추가로 조건절이 있다면 (+) 연산자를 모두 해야 한다.

// ename LIKE 조건절에 (+) 연산자가 누락된 경우

1
2
3
4
SELECT DISTINCT(a.deptno), b.deptno
FROM emp a, dept b
WHERE a.deptno(+= b.deptno
  AND a.ename LIKE '%';
cs

[결과] DEPTNO     DEPTNO
        ---------- ----------
                10         10
                20         20
                30         30

 

// ename LIKE 조건절에 (+) 연산자를 추가해야 정상적으로 데이터가 조회된다. 

1
2
3
4
SELECT DISTINCT(a.deptno), b.deptno
  FROM emp a, dept b
 WHERE a.deptno(+= b.deptno
   AND a.ename(+LIKE '%';
cs

[결과] DEPTNO  DEPTNO
         ------- --------
             10       10
             20       20
             30       30
                       40

728x90
반응형