티스토리 뷰

컴퓨터 공학과 졸업/데이터베이스

SQL

심재철 2017. 10. 19. 10:53

Q.빨간색 보트와 초록색 보트를 예약한 선원의 아이디를 구하시오

둘다 가능하다. 왼쪽에서 보면 Range variable을 이용해서 같은 릴레이션을 2개로 나누었다 B1,B2로 나누었기 때문에 AND연산이 가능한것이다.

만약에 2개로 나누지 않고 그냥 Boats B해놓고 B.color='red' AND B.color = 'green'이런식으로 하면 

하나의 보트가 빨간색과 초록색을 동시에 가진다는 뜻이다.


바깥 쿼리문을 outer block 안쪽 쿼리문을 inner block이라고 부르며 IN연산자는 =와 같다.

inner block부터 처리하게 된다.(조인 대신에 중첩질의를 사용한것)

중첩질의는 질의를 2개나 처리하는것과 마찬가지이므로 비싼 연산이다.


오른쪽 쿼리문은 바깥 Sailors의 이름을 하나씩 가져와서 이너블락 실행하고 하나가져와서 이너블락 실행하고 이런식으로 동작하기 때문에

굉장히 느리다.


inner block의 결과가 2,5,7이라고 할때 그 어떤 것보다 크기만 하면 되므로 S중 3이상을 가진 등급을 가진 사람의 레코드만 나오게 될것이다.

ANY대신 ALL이라고 하면 모든것보다 커야 되므로 8이상을 가진 사람의 레코드만 나온다.


쿼리문 : 빨간색과 초록색 보트를 모두 예약한 선원의 아이디를 구하시오.


왼쪽은 결과를 모두 구한뒤에 INTERSECT를 해준것이고 오른쪽은 중첩질의를 통해서 빨간색과 초록색 배를 둘다 예약한 사람의 아이디를 찾는다

왼쪽과 오른쪽의 결과가 같다.


SQL문에서는 디비젼 연산이 따로 없기 때문에 다른 연산자들의 조합으로 복잡하게 작성해야한다.



가장 나이가 많은 선원의 이름과 나이를 구해라.

-> 1,2번은 가능 3번은 불가능

3번 같은 경우에는 모든 선원의 이름과 나이가 출력되는데 모든 선원의 나이가 age중 최고값으로 세팅 되서 결과가 나올것이다.

하지만 우리가 원하는 결과는 딱 1개의 레코드이다.(가장 나이가 많은 선원의 이름과 나이를 가지는 딱 1개의 레코드)


선원의 등급별로 최소나이를 알고 싶을때 위의 쿼리문처럼 반복문에 쿼리문을 집어 넣을수도 있지만 이럴경우 몇개의 등급이 존재할지 

미리 모르는 경우가 많다. 그렇기 때문에 위 처럼 반복시키면 안된다.

=> GROUP BY와 HAVING필요



GROUP-BY를 사용할때 해석 순서는 다음과 같다.

1.FROM 뒤에 나오는 릴레이션들을 크로스 프로덕트 한다.

2. WHERE절에 조건을 만족하는 레코드만 선별한다(셀렉트)

3. GROUP-BY연산자로 그룹을 짓는다.

4. 그 각각의 그룹이 HAVING절 뒤의 조건을 만족할 경우 SELECT를 실행한다.

1. FROM절 크로스 프로덕트

2. WHERE절 셀렉션 결과로 zorba가 빠짐

3.등급별로 그룹을 짓는다. 1,7,7,8,10으로 그룹이 지어짐.

4.그룹의 개수가 2이상인것만 셀렉트 문을 실행시킴

5.등급이 7인 그룹만 HAVING절을 만족하므로 셀렉트문이 실행되서 rating 7 age는 7등급 그룹의 최소나이인 35.0이 출력된다.






댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함