목차
📁 Select문
데이터베이스에서 기본적으로 검색하고자 할 때 Select문을 사용한다.
Select문은 SELECT절, FROM절, WHERE절 총 세가지 절로 구성된다.
SELECT절은 결과적으로 도출될 릴레이션이 가질 애트리뷰트를 지정한다.
FROM절은 지금 작성하는 SQL문장의 입력으로 사용할 테이블을 지정한다.WHERE절은 지금 질의를 수행하기 위해 검색되는 튜플들을 명시하는 조건식을 지정한다. 선택사항이다.
SELECT * FROM Customer WHERE lastName = 'Doe'
'Doe'라는 성을 가진 고객을 찾기 위한 Select문이다.
* SELECT절에서 별표(*)는 입력 테이블의 모든 애트리뷰트를 명세한다.
* 'Doe'와 같이 문자열은 작은따옴표(')로 둘러싸 표시한다.
WHERE절은 질의의 조건을 명시하는 역할이므로, WHERE절이 없으면 FROM절에서 명시한 릴레이션에서, SELECT절에 명시한 애트리뷰트들만 보여주며 모든 튜플들이 질의 결과로 나올것이다.
select *
from TimeCard
where ssn=‘376-77-0099’ and date>’01-mar-1999’
select lastName, firstName
from Customer
DISTINCT
select distinct lastName, firstName
from Customer
LIKE 비교 연산자
SELECT문의 WHERE절에서 조건을 명시할 때, 패턴매칭(Pattern Matching)을 하기 위해 사용한다.
like ... 은 ...와 일치하는 튜플을 검색하고,
not like ... 은 ...와 일치하지 않는 튜플을 검색한다.
... 부분은 패턴매칭에서 패턴을 나타내며, 대소문자를 구분한다.
select *
from Movie
where genre like ‘%comedy’
장르가 'comedy'로 끝나는 모든 영화를 검색하는 코드이다.
패턴 부분에서 사용하는 퍼센트(%)는 임의의 가변 길이 문자열을 대표한다.
위 예시에서는 %comedy와 같이 사용되었고, 이는 임의의 가변 문자열 뒤에 comedy가 붙는 문자열을 의미하므로
곧 comedy로 끝나는 문자열이 되는 것이다.
select *
from Employee
where ssn like ‘_ _ _-44-_ _ _ _’
SSN의 가운데 두 가지가 44인 모든 직원을 검색하는 코드이다.
패턴 부분에서 사용하는 언더스코어(_)는 하나의 문자를 대표한다.
위 예시에서는 '___-44-____'와 같이 사용하였고, 이는 앞에 3자리, '-44-', 뒤 4자리를 갖는 문자열을 의미하므로
곧 가운데 두자리가 44인 문자열이 되는것이다.
AS절
SELECT절에서 결과 릴레이션의 애트리뷰트를 지정하는 표현식으로
문자열 / 숫자 / 애트리뷰트 / 산술식 / 함수호출이 올 수 있다.
이때 AS절을 이용하여 질의 결과 릴레이션의 애트리뷰트에 새로운 이름을 부여할 수 있다.
select lastName,
firstName,
Employee.ssn,
date,
(endTime-startTime) * 24 as hoursWorked
from Employee, TimeCard
where Employee.ssn = TimeCard.ssn
위에서 (endTime - startTime) * 24를 보면, 표현식에서 -, *와 같은 산술식, 24와 같은 숫자를 사용하였다.
이를 AS절 없이 보여주면 위 결과 릴레이션에서 애트리뷰트 이름이 (endTime - startTime) * 24 그대로 나타나므로,
as hoursWorked 코드로 새 이름을 부여하는 것이다.
ORDER BY절
결과 릴레이션의 튜플들이 특정 순서로 반환될 수 있도록 지정할 때 사용한다.
기본 값은 오름차순 정렬(asc)이다.
select *
from Customer
order by lastName, firstName
모든 고객 정보를 검색하여, 고객의 성과 이름을 기준으로 오름차순으로 정렬
select *
from Customer
order by accountId desc
모든 고객 정보를 검색하여, accountId의 값에 따라 내림차순으로 정렬
select *
from Customer
order by lastName desc, zipcode asc
모든 고객 정보를 검색하여, lastName은 내림차순, zipcode는 오름차순으로 정렬
JOIN
두 개의 테이블을 이용하여 Select문을 작성할 때 사용한다.
select *
from Employee, TimeCard --(입력 테이블)
where Employee.ssn = TimeCard.ssn --(조인 조건 or 선택 조건)
select *
from Employee join TimeCard
on Employee.ssn = TimeCard.ssn --(조인된 테이블)
조인 연산을 명시적으로 표현할 때 두 테이블 사이에 JOIN 키워드를 사용하고,
이때 WHERE절 대신 ON절로 조인 조건을 표시한다.
즉 위 코드의 두 Select문은 같은 기능을 수행한다.
집단화 함수
여러 튜플의 정보를 요약하여 하나의 튜플로 요약하는데 사용하는 함수를 말한다.
SELECT절이나 HAVING절에 사용되는 count, avg, sum, min, max ... 등의 함수이다.
--질의 : 고객 번호 101인 고객이 현재 대여 횟수를 검색하라.
select count(*)
from Rental
where accountId =101
--질의 : 고객의 성(lastName)의 개수를 검색하라.
select count (distinct lastName)
from Customer
--질의 : 직원들의 평균 근무 시간을 계산하라.
select avg((endTime-startTime) *24) as avghoursWorked
from TimeCard
GROUP BY절과 HAVING절
📌 같은 컬럼 값에 대해 튜플들의 그룹을 구성할 때 GROUP BY절을 사용한다.
GROUP BY 키워드 뒤에 그룹핑 애트리뷰트(Grouping Attribute)를 명시하는 방법으로 사용한다.
이때 그룹핑 애트리뷰트는 결과 릴레이션의 애트리뷰트 중 같은 컬럼 값을 묶고 싶은 애트리뷰트를 말한다.
GROUP BY절을 사용할 경우, SELECT절에는 그룹핑 애트리뷰트와 튜플들의 각 그룹에 적용할 집단 함수만 포함되어야 한다.
select videoId,
avg(cost) as averageCost,
count(*) as numRentals
from PreviousRental
group by videoId
위 코드에서 그룹핑 애트리뷰트는 videoId이고, videoId의 같은 값들을 그룹핑한다.
이때 SELECT절에는 위에서 설명했듯이 그룹핑 애트리뷰트인 videoId와, 튜플들의 각 그룹에 적용할 집단함수들로 이루어져있다.
튜플들의 각 그룹이란, 위 테이블에서 예를 들어보면 videoId 값이 같은 튜플들의 집단이다.
즉 PreviousRental에서 1,2번째 튜플, 3번째 튜플, 4,5,6번째 튜플, 7번째튜플, 8번째튜플이 각 그룹이고,
결과 릴레이션의 1번째 튜플을 보면 PreviousRental의 1, 2번째 튜플의 Cost를 평균낸 값이 averageCost 애트리뷰트 값으로 들어가는것처럼, avg와 count함수는 각 그룹별로 수행된다.
📌 그룹에 셀렉션 연산을 적용할 때 HAVING절을 사용한다.
HAVING절의 조건을 만족하는 그룹만 결과 릴레이션에 반영되며,
위 SELECT절에서 가능한 애트리뷰트는 HAVING절에서도 사용할 수 있다.
select *
from Movie, Videotape, PreviousRental
where Movie.movieId = Videotape.movieId
and Videotape.videoId = PreviousRental.videoId
먼저 기본적으로 세개의 릴레이션에 위 코드와 같이 WHERE절로 조건을 적용하면 이와 같다.
select *
from Movie, Videotape, PreviousRental
where Movie.movieId = Videotape.movieId
and Videotape.videoId = PreviousRental.videoId
group by Movie.movieId, title, genre
having count(*) >=2
위 코드에서 GROUP BY절과 HAVING절을 추가하면 이와 같다.
GROUP BY로 movieId를 그룹화했는데 같은 아이디의 튜플이 묶이지 않은 이유는 같은 그룹안의 각 튜플마다 cost와 accountId와 같이 다른 값이 존재하기 때문이다.
select title,
genre,
count(*) as numRentals,
avg(cost) as avgCost,
sum(cost) as totalCost
from Movie, Videotape, PreviousRental
where Movie.movieId = Videotape.movieId
and Videotape.videoId = PreviousRental.videoId
group by Movie.movieId, title, genre
having count(*) >=2
최종적으로 집단화함수까지 사용하면 이와 같다.
count(*), avg(cost), sum(cost)처럼 각 그룹이 하나의 값을 가질 수 있는 애트리뷰트들만 SELECT절에 나타냈으므로, 위와 같이 그룹화가 되어 결과 릴레이션이 나왔다.
HAVING절을 보면 COUNT(*) 애트리뷰트를 사용했는데, SELECT절에서 애트리뷰트로 사용이 가능하고, 실제로 사용되고 있으므로 HAVING절에서 사용이 가능하다.
중첩 질의(Nested Query)
WHERE절 안에 또 다른 SELECT문이 있는 질의를 중첩 질의라고 한다.
어떤 원소가 주어진 집합에 있는지 검사하는 역할로,
WHERE절에 비교연산자 IN 키워드를 사용한다.
--단일 SQL 질의 표현
select *
from Customer, PreviousRental
where Customer.accountId=PreviousRental.accountId
and dateRented >= ‘dec/1/1998’ and dateRented< ‘1/1/99’)
--중첩 질의 표현
select *
from Customer
where accountId in
(select accountId
from PreviousRental
where dateRented >= ‘dec/1/1998’
and dateRented< ‘1/1/99’)
PreviousRental 테이블에서 dateRented(대여날짜)가 1998년 12월동안인 튜플의 accountId들을 구하면 하나의 집합이 된다.
즉 이 집합은 PreviousRental의 accountId들의 부분집합이고, 이 집합 안에 Customer의 accountId가 있는지 하나씩 검사하여 결과를 낸다.
select *
from Customer C
where not exists (select *
from PreviousRental P
where C.accountId = P.accountId)
EXISTS함수는 EXISTS 키워드 다음에 오는 질의문의 결과가 존재하는지 검사하는 함수이다.
PreviousRental 테이블에서 Customer의 accountId와 같은 accountId를 지닌 튜플을 찾는 것이 NOT EXISTS 키워드 다음의 질의문 결과이다.
PreviousRental 테이블에 101이 3개, 102는 1개, 103은 0개, 104는 0개, 106은 0개, 111은 2개, 201은 2개, 444는 0개이므로, NOT EXISTS 함수의 결과가 참인 accountId는 103, 104, 106, 444이다.
EXISTS 외에도 ALL, UNIQUE, CONTAINS, NOT 등이 중첩 질의문에 사용되는 연산자이다.
집합 연산자
집합연산에는 합집합(Union), 교집합(Intersect), 차집합(Except)이 있다.
열의 수가 같고 열들이 순서대로 같은 타입을 가지는 경우 호환성이 있다고 판단하여, 어떠한 두 개의 테이블에 대해서 사용 가능하다.
중복된 튜플은 결과에서 제거된다.
select *, ‘Rental’ as sourceTable
from Rental
union
select *, ‘PreviousRental’ as sourceTable
from PreviousRental;
📁 SELECT문 실행 순서
1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. HAVING
7. SELECT
8. DISTINCT
9. ORDER BY
10. TOP
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY