Select에 대해
IN
IN
v IN (v1, v2, v3 ….) 에서 v 가 (v1, v2, v3 …) 중에
하나라도 값이 같다면 TRUE
를 return 한다.(v1, v2, v3 …) 는 명시적인 값이 될 수도 있고, subquery의 결과 (set or multiset)일 수도 있다.
NOT IN
- v NOT IN (v1, v2, v3 ….) 의
모든 값과 값이 다르면 TRUE
를 return 한다.
select * from member m where m.id in (2, 10);
# 멤버의 아이디가 2 or 10인 값 return
unqualified attribute
unqualified attribute란 앞에 어떤 테이블의 attribute인지 명시하지 않은 attribute를 뜻 한다.
이러한 attribute의 경우 서브쿼리로 사용 시 어떤 table의 attribute인지 알 수 없다. 이러한 경우 mysql에서는 해당 attribute에서 가장 가까운 table을 참조한다고 알아두자.
EXISTS
EXISTS
- subquery의 결과가
최소 하나의 tuple이라도 있다면 TRUE
를 return한다.
NOT EXISTS
- subquery의 결과가
단 하나의 tuple도 없다면 TRUE
를 return 한다.
correlated query
subquery가 바깥쪽 query의 attribute를 참조
할 때 그 subquery를 correlated subquery
라고 부른다.
IN
과 EXISTS
는 서로 바꿔가며 사용가능하다. 둘의 성능 차이가 거의 없다.
ANY
ANY
- v 비교연산자 ANY (subquery) :
subquery가 반환한 결과들 중 단 하나라도 v와의 비교 연산이 TRUE라면 TRUE
를 return 한다.
SOME
과 ANY는 같은 역할을 한다.
ALL
ALL
- v 비교연산자 ALL (subquery) :
subquery가 반환한 결과들과 v와의 비교 연산이 모두 TRUE라면 TRUE
를 return 한다.
NULL
IS
IS
는 NULL과 비교하기 위한 연산자이다.
UNKNOWN
UNKNOWN
은 SQL에서 NULL과 비교 연산을 하게 될 때 나오는 결과
이다. TRUE 일 수도 있고, FALSE 일 수도 있다
라는 의미다.
three-valued logic
비교/논리 연산의 결과로 TRUE, FALSE, UNKNOWN을 가진다는 의미
이다.
NULL과 비교연산 시
위 그림과 같이 결과가 나온다.
논리연산 시 UNKNOWN이 포함되었을 때 위와 같은 결과가 나온다는 것을 유의하자.
위의 연산 결과를 유의하지 않는다면 쿼리 작성 시 예상하던 값과 다른 값이 나올 수 있다.
대표적으로 where절에서 문제가 발생할 수 있다.
WHERE절의 condition
- where절에 있는
condition의 결과가 TRUE인 tuple만 선택
된다. - 즉, 결과가
FALSE 이거나 UNKNOWN인 tuple은 선택되지 않는다.
이런 특성 때문에 UNKNOWN에 대해 명심해야된다.
예제를 통해 살펴보자.
NOT IN
사용 시
v NOT IN (v1, v2, v3)
을 풀어서 서술한다면 다음과 같다.
v != v1 AND v != v2 AND v != v2
이때 v1, v2, v3 중 하나가 NULL이라면 어떻게 될까?
위와 같은 결과가 나오기 때문에 3 not in (1, 2, NULL)에서 예상하던 결과랑 다른 결과가 나오고 만다.
이런 문제를 잘 유의하며 쿼리를 작성해야한다.
JOIN
implicit join
from 절에는 table
들만 나열하고where 절에 join condition
을 명시하는 방old-style join syntax
- where 절에 selection condition과 join condition 이 같이 있어
가독성이 떨어짐
- 복잡한 join 쿼리를 작성하다보면
실수를 유발
함
explicit join
from 절에 JOIN 키워드와 함께 joined table들을 명시
하는 방식from 절에서 ON 뒤에서 join condition을 명시
한다.가독성이 좋음
- 복잡한 join 쿼리 작성시
실수할 가능성이 적음
inner join
INNER JOIN table ON v = v1
과 같은 식으로 사용한다. 앞에 INNER는 생략 가능두 table에서 join condition을 만족하는 tuple
들로 result table을 만드는 joinjoin condition에
=, <, >, != 등 여러 비교연산자 사용 가능
join condition에서
null 값을 가지는 tuple은 result에 포함 X
outer join
두 table 에서 join condition을 만족하지 않는 tuple
들도 result table에 포함하는 joinLEFT, RIGHT, FULL
3 종류가 있다.- join condition에
=, <, >, != 등 여러 비교연산자 사용 가능
LEFT JOIN
- from 절의
왼쪽 테이블
에 있는join condition에 매칭되지 않는 tuple들까지도 result table에 포함
시킨다.
RIGHT JOIN
- from 절의
오른쪽 테이블
에 있는join condition에 매칭되지 않는 tuple들까지도 result table에 포함
시킨다.
FULL JOIN
- mysql에서는 FULL OUTER JOIN은 지원하지 않지만 다른 sql에서는 지원
- from 절의
모든 테이블
에 있는join condition에 매칭되지 않는 tuple들까지도 result table에 포함
시킨다.
equi join
- join condition에서
= (equality comparator)를 사용하는 join
- equi는
inner join에서 =를 사용한 경우에만 equi join으로 보는 시각
과inner, outer 상관없이 =를 사용한 join이라면 equi join으로 보는 시각
이 있다.
- equi는
USING
두 테이블에 같은 이름을 가지는 attribute를 equi join 시 사용
할 수 있다.이때 해당 attribute는 result table에
한번만 표시
된다.ex)
# USING 사용 전 select * from employee E INNER JOIN department D ON E.dept_id = D.dept_i #------------------------------------------------------------------------- # USING 사용 후 select * from employee E INNER JOIN department D USING (dept_id);
USING 사용 전
USING 사용 후
natural join
두 table에서 같은 이름을 가지는 모든 attribute pair에 대해서 equi join을 수행
한다.- join condition을 따로 명시하지 않음
같은 이름을 가진 attribute의 경우
USING과 같이 앞으로 나오게 된다.
같은 이름을 가지는 모든 attribute pair에 대해 equi join을 수행하기 때문에 그 부분을 유의하자.
cross join
두 table 의 tuple pair로 만들 수 있는 모든 조합
을 result table에 포함join condition이 없다.
implicit cross join : FROM table1, table2
explicit cross join : FROM table1 CROSS JOIN table2
둘 다 같은 의미
- 위와 같이 두 table의 모든 tuple들이 서로 매칭된 결과가 나온다.
- cross join @ MySQL
- MySQL에서는 cross join = inner join = join 이다.
- CROSS JOIN에
ON(or USING)을 같이 쓰면 inner join으로 동작
함 - INNER JOIN (or JOIN)이
ON(or USING) 없이 사용되면 cross join으로 동작
ORDER BY
- 조회 결과를
특정 attribute 기준으로 정렬
해 가져오고 싶을 때 사용 - default는 오름차순
- 오름차순 :
ASC
- 내림차순 :
DESC
만약 두개 이상의 attribute들을 정렬하고 싶을 땐 다음과 같이 작성하면 된다.
이때 ORDER의 순서는 앞에 dept_id를 기준으로 정렬 후 salary를 기준으로 정렬하게 된다. NULL의 경우엔 제일 앞에 정렬된다.
aggregate function
여러 tuple들의 정보를 요약해서 하나의 값으로 추출하는 함수
- 대표적으로 COUNT, SUM, MAX, MIN, AVG 함수가 있다.
- (주로) 관심있는 attribute에 사용된다.
NULL 값들은 제외
하고 요약 값을 추출한다.
ex) 임직원 수를 알고 싶을 때의 예제 (result = 16)
SELECT COUNT(*) FROM employee;
# 결과 : 16
#########################################
SELECT COUNT(position) FROM employee;
# 결과 : 16
#########################################
SELECT COUNT(dept_id) FROM employee;
# 결과 : 14
(*)
을 사용할 경우 모든 tuple들에 대해 count한 결과가 나오고, position
도 같은 값이 나온다.
하지만 dept_id
의 경우 tuple의 갯수인 16이 아니라 14가 나왔다.
그 이유는 dept_id에는NULL 값이 포함되어 있기 때문이다. 이렇듯 NULL 값을 제외하고 값을 구하기 때문에 웬만하면 (*)를 사용
하자.
GROUP BY
- 관심있는 attribute 기준으로 그룹을 나눠서
그룹별로 aggregate function을 적용
시킬 때 사용 - grouping attribute : 그룹을 나누는 기준이 되는 attribute
- grouping attribute에 NULL 값이 있을 때는 NULL 값을 가지는 tuple끼리 묶인다.
ex)
SELECT CONUT(*), MAX(salary), MIN(salary), AVG(salary)
FROM works_on W JOIN employee E ON W.empl_id = E.id
WHERE W.proj_id = 2002;
GROUP BY 사용해 그룹별 조사
SELECT W.proj_id, CONUT(*), MAX(salary), MIN(salary), AVG(salary)
FROM works_on W JOIN employee E ON W.empl_id = E.id
GROUP BY W.proj_id;
- SELECT 문에 GROUP BY에 있는 attribute를 적어줘야한다.
having
- GROUP BY와 함꼐 사용함
- aggregate function의
결과값을 바탕으로 그룹을 필터링하고 싶을 때 사용
- HAVING 절에 명시된
조건을 만족하는 그룹만 결과에 포함
ex)
SELECT W.proj_id, CONUT(*), MAX(salary), MIN(salary), AVG(salary)
FROM works_on W JOIN employee E ON W.empl_id = E.id
GROUP BY W.proj_id
HAVING COUNT(*) >= 7;
COUNT의 결과값이 7 이상인 그룹만 가져온다.
SELECT 실행 순서
출처)