데이터베이스

SQL4: Select SQL Statement1

소재훈 2021. 12. 21. 02:16

데이터베이스 목차

이 글에서는 University Database가 사용된다.

SELECT Statement

Select문은 대용량의 데이터베이스에서 원하는 정보를 검색할 때 사용한다.  구조는 다음과 같다.

select statement

SELECT 절은 관계 대수의 project(∏)와 동일한 역할을 한다.

SELECT *
FROM professor;

SQL에서의 에스더리스크(*)는 '모든 속성'을 의미한다.

 

SELECT pID, name, deptName, salary/12
FROM professor;

SELECT절에서 상수나 계산식을 사용할 수도 있다. 위 SQL에서는 salary의 값을 12로 나눈 값을 출력하도록 되어있다.

관계 대수와 다르게 SQL은 중복을 허용한다. 여기서의 중복은 tuple에 대한 중복을 말한다. (=여러 개의 tuple이 한 테이블에 존재할 수 있다.)

 

결과 테이블의 중복을 없애고 싶다면 다음과 같이 distinct를 사용한다.

SELECT distinct deptName
FROM professor;

 

결과 테이블의 중복을 허용하고 싶다면 all 키워드를 사용하면 된다. 아무것도 쓰지 않으면 이 all키워드가 기본값이다.

SELECT all detpName
FROM professor;

WHERE Clause

결과테이블에서 원하는 조건을 만족하는 튜플을 찾아내기 위해 조건을 걸 때 사용한다.

ex) professor 테이블에서 CS학과이면서 연봉이 8000보다 높은 교수의 이름을 찾으시오.

Select name
from professor
where deptName = 'CS' and salary > 8000;

조건문에서 'and', 'or', 'not'을 사용해서 조건을 표현할 수 있다.


FROM Clause

검색할 테이블을 나타내는 절이다 여러테이블을 적으면 Cartesian product를 수행한다. 

Select *
From professor, teaches;

professor테이블과, teaches테이블을 cartesian product를 수행한 결과가 결과 테이블이 된다.

 

의미 있는 튜플은 대부분 공통되는 column의 값이 같은 것이기 때문에 일반적으로 Cartesian Product를 수행했을 때 나오는 중간 table에서 의미 있는 테이블을 한번 더 필터링하는 작업이 필요하다. 따라서 두 개의 table을 사용하는 경우 대부분의 경우 Where절이 필요하다.


Joins

SQL에서 join을 위해서 어떤 연산이 주어지는지 살펴보자.

Select name, cID
From teaches, course, professor
Where teaches.pID = professor.pID;

From절에 두개의 테이블을 쓰면 내부적으로 Cartesian Product가 일어나 대부분의 경우에는 공통되는 column의 값이 같은 튜플이 의미가 있으므로 Where절이 필요하다. 즉 Cartesian Product를 통해서 Join을 표현할 수 있다.

 

ex) CS학과에서 개설된 교과목과 교수 이름을 출력하시오.

이 문제를 해결하기 위해서는 teaches, course, professor 세 개의 테이블에 있는 정보가 필요하다.

Select title, name
From teaches, course, professor
Where teaches.cID = course.cID and teaches.pID = professor.pID and course.deptName = 'CS';

 

두 번째로 natural join을 이용해서 Join을 표현할 수 있다. natural join은 공통되는 column을 하나로 해준다는 점에서 cartesian product와 달랐다는 것을 기억하자. 하지만 다음과 같이 속성의 이름은 같지만 실제로는 다른 속성을 가지는 경우도 있으므로 주의 해야한다.

Select name, title
from professor natural join teaches natural join course;

위 SQL문을 수행하면 professor, course 테이블의 deptName 속성이 이름이 같이 동일한 속성으로 간주되지만 실제로 두 속성은 다르므로 위 SQL문은 틀렸다. 올바르게 작성하려면 cartesian product를 통해서 직접 공통된 속성을 지정해주거나, 다음과 같이 using 키워드를 사용하여 공통으로 사용할 속성을 지정해 줄 수 있다.

Select name, title
from professor natural join teaches, course
where teaches.cID = course.cID;

Select name, title
from (professor natural join teaches) join course using(cID);

Select name, title
from teaches, course, professor
where teaches.cID = course.cID and teaches.pID = professor.pID;

Rename Operations

as 키워드를 사용하여 속성이나 테이블 이름을 재명명해줄 수 있다. as를 생략하고 작성해도 동일한 기능을 한다.

Select pID , name, salary/12 as monthlySalary
from professor;

Select sID , name myName , deptName
from student;

첫 번째 SQL에서 salary 속성 값을 12로 나눈 속성 이름을 monthlySalary로 재명명했고, 두 번째 SQL에서는 name 속성을 myName이라는 이름으로 재명명했다. 재명명을 해두면 SQL에서 해당 이름으로 사용할 수 있다.

 

ex) CS학과의 '어떤' 교수보다 높은 연봉을 받는 교수의 이름을 찾아라.

다른 말로 하면 CS학과에서 최저 연봉을 받는 사람보다 많은 연봉을 받는 사람들을 찾으라는 의미이다. 이렇게 동일한 테이블에서 조건을 따져야 하는 SQL문은 동일한 테이블 두 개를 재명명해서 찾는 것으로 정형화되어있다.

Select distinct T.name
from professor as T, professor as S
where T.salary > S.salary and S.deptName = 'CS';

professor테이블 두 개를 각각 T와 S로 재명명하고 한 명이라도 자기보다 낮은 연봉을 가지는 교수 튜플이 있으면 교수의 이름을 중복 없이 출력한다.


String Operation

  • percent(%): 어떤 substring이라도 올 수 있다는 것을 나타낸다.
  • underscore(_): 어떤 문자 하나가 올 수 있다는 것을 나타낸다.

위의 기호들을 이용해서 like 키워드와 함께 문자열을 매칭 할 수 있다.

Select name
from professor
where name like '%da%';

da라는 문자열이 포함된 모든 교수의 이름을 출력하고 있다.

 

'100%'라는 문자를 포함하는 문자열을 탐색할 때는 단순히 %만 써주게 되면 substring을 의미하게 되므로 escape 문자로 사용할 문자를 써준후, 어떤 문자열이 escape역할을 해줄지 명시해주어야 한다.

Select cID
from course
where title like ‘100\%' escape '\';

'데이터베이스' 카테고리의 다른 글

SQL6: Null Values  (0) 2021.12.23
SQL5: Select SQL Statement2: Duplication, Set Operation  (0) 2021.12.23
SQL3: DML SQL  (0) 2021.12.20
SQL2: DDL SQL  (0) 2021.12.20
SQL1: DDL/DML/DCL/Procedure VS Non-procedure  (0) 2021.12.20