SQL part1) select

Yona·2021년 10월 26일
0

🌙 CS_DataBase

목록 보기
7/10

select

사용자가 보고 싶은 속성 리스트가 결과.

  • relational algebra 의 project operation에 대응
    • : 모든 attribute 의미
  • arithmetic expression + 시스템 제공 함수(log, square등) 활용 가능
  • 튜플 중복 허용
    • 중복 허용하지 않으려면 distinct 키워드 사용
      • ex) Select distinct deptName from professor; // Find the names of all departments with professors, and remove duplicates
  • 중복 허용은 디폴트이며, all 키워드 사용
    • ex) Select all deptName from professor;

where 절

tuple이 만족해야하는 조건 명시

  • linear algebra의 select predicate에 해당
  • 논리 연산자 사용 가능
    • and, or, not
    • 산술 연선자보다 더 후순위이다.
    • ex) select name from professor where deptName='CS' and salary > 8000;

from 절

질의에 관련있는 테이블 나열

  • 테이블 나열시 카타시안곱 연산에 대응
    • select * from professor, teaches; // 카타시안곱 연산
    • 카타시안곱 연산 자체보단, where절과 함께 유용하게 쓰이는 편

execution 순서

  1. from 절에 명시된 각 테이블에서 each 튜플 추출
  2. 추출된 튜플들에 where 조건 적용
  3. where 조건 판정난 튜플들을 group by 절로 보내서, 참으로 만드는 모든 튜플 조합 구한 후 group by 속성 이용해서 중간결과를 subgroup으로 나눈다.
  4. 각 sub group들에 having 조건 적용하여 조건을 참으로 만드는 sub group 구한다
  5. 이 sub group들에 order by 조건 대로 정렬하여 결과 테이블로 만든다.

join

join은 공통 column을 가지는 tuple끼리 새로운 table을 만든다.

inner joinnatural join
중복 허용 O중복허용 X

|

ex)

// natrual join. 7개
Select * __from professor natural join teaches__; // inner(=default) join. 8개
Select * __from professor, teches__ where professor.pID = teches.pID; 

(inner) join

  • find professor names and course IDs they taught
Select name, cId // 3. 이름과 cID 검색
from professor, teaches // 1. 중간테이블 만들어짐
where professor.pId=teaches.pID; // 2. 둘의 pID가 같은 튜플 중
  • find the titles of courses offered by the ‘CS’ department, and names of professors who teach the courses
Select title, name // 3. title, name만 추출
from teaches, course, professor // 1. 이 테이블들의 카티시안곱 테이블 만들어낸 다음
where teches.cID=course.cId and teches.pID=professor.pID and course.deptName='CS'; // 2. 조건들 만족시키는 튜플 들 중

natural join

테이블에 대하여 자연 조인을 적용할 때에는 동일한 이름을 가진 속성으로 인하여 원하지 않은 조인 연산이 일어나지 않도록 주의하여야 한다.

예시)

// 잘못된 ver
Select name, title
from professor natural join teches natural join course;

// 올바른 ver1
Select name, title
from professor natural join teaches, course // prof<-> teaches는 Natural join 하고 그 뒤 course는 일반 조인
where teaches.cID = course.cID;

// 올바른 ver2
Select name, title
from (professor natural join teaches) join course using(cID);

// 올바른 ver3
Select name,title
from teaches, course, professor
where dteaches.cID=course.cID and teaches.pID=professor.pID;

Rename "as"

  • 새로운 이름으로 재명명한다.
  • 예시
    • Select pID, name, salary/12 as monthlySalary from professor;
  • ⚠️ 생략가능하다
    • ex) professor as T = professor T
    • ex) Select sID, name myName, deptName from student;
  • 테이블 이름도 재명명 가능
    • ex) Select distinct T.name from professor as T, professor as S where T.salary > S.salary and S.deptName='CS';

string 비교 연산

like 연산자 + 패턴(%,_ 등)

  • %
    • 길이에 무관한 임의의 스트링 (empty string 포함)
    • Select name from professor where name like '%da%'
  • _
    • any single char
  • 탈출문자로 혼동방지
    • ex) "100%"를 찾는경우, where title like '100\%' escape '\'
  • 이 외에도 concat(||), 대소문자 변환, extracting 등 다양한 string operation 존재

order by

order by로 다른 테이블 생성하는게 아니라, 결과 테이블에 들어가는 튜플 순서에 변화를 준다.

  • 순서
    • 내림차순 : "desc"
    • 오름차순 : "asc" (default)
      • Select distinct name from professor order by name;
  • multiple attribute 정렬도 가능
    • Order by deptName desc, name

between

  • where절에 사용할 수 있는 연산자로서 값 구간을 의미(경계 값도 포함)
  • between A and B

예시

  • To find the names of all professors with salary between 5000 and 6000 including boundaries
    • Select name from professor where salary between 5000 and 6000;```

튜플 비교

ex)

Select name, cID
from professor, teaches
where (professor.pID, deptName) = (teaches.pID, 'CS') // 튜플 비교

중복

SQL은 tuple 중복을 허용한다(i.e. multiset)

  • 연산시 : 중복에 상관없이 입력 테이블의 모든 튜플에 대하여 연산을 하는 것
  • 결과 : 모든 튜플이 중복에 상관없이 결과 테이블에 속한다.

집합 연산

SQL은 집합연산도 지원한다

  • set 이니까 중복 허용 X
  • all 키워드 사용시 중복허용(multiset)
    • union all, intersect all, except all
  • union
    • m+n times in “r union all s” // duplicate 허용하기때문
  • intersect
    • min(m, n) times in “r intersect all s”
  • except
    • max(0, m–n) times in “r except all s
  • 예시
    • Find course IDs that ran in Fall 2009 or in Fall 2010
      • (select cID from teaches where semester='Fall' and year = 2009) union (select cID from teaches where semester='Fall' and year=2010);
  • Find course IDs that ran in Fall 2009 and in Fall 2010
    • (select cID from teaches where semester='Fall' and year=2009) intersect (select cID from teaches where semester='Fall' and year=2010)
  • Find course IDs taht ran in Fall 2009 but not in Fall 2010
    • (select cID from teaches where semester='Fall' and year=2009) except (select cID from teaches where semester='Fall' and year = 2010);

Null

값이 존재하나 아직 알려지지 않는 경우, 값이 원천적으로 존재하지 않는 경우, 값 존재 여부가 확인되지 않은 경우 등

  • NULL의 처리
    • 예상하지 못한 결과를 초래하기도 한다.
    • null이 포함되는 산술연산 결과는 NULL
      • 5 + null = null
    • 존재여부 확인
      • is null / is not null
      • select name from professor where salary is null;
    • null이 포함되는 비교연산 결과는 unknown
      • 5 < null, null <> null, null = null
    • Three-valued logic
      • 세 값 논리의 사용으로 SQL select 문장에서 where절 결과가 참/거짓/모름으로 나올 수 있으며, where절 결과가 참인 경우에만 그 결과를 사용자에게 반환된다.
      • where절 결과가 모름인 경우에는 거짓의 경우와 마찬가지로 그 결과를 사용자에게 반환하지 않는다.
      • unknown = 0.5로 취급
        • true AND false = min(1,0)=0=false
        • true OR unknown = max(1,0.5)=1=true
        • not false=1-0=1=true
        • not unknown=1-0.5=0.5=unknown

Exercises

  • Find student names and department names of students whose GPA is below 2.0
Select name, deptName
from student
where GPA < 2.0;
  • Find the student names who have taken at least one course of ‘CS’ department. Make sure that there are no duplicate names in the result
select distinct name
from student, course, takes
where takes.cID=teaches.cID and teaches.cID='CS' and student.sID=takes.sID and student.cID=teaches.cID;

select distinct name
from student, (course natural join takes) using (sID)
where course.deptName='CS'
where 
  • Retrieve the chairperson name, his/her salary, and the name of department he/she is in charge of
Select name, salary, department.deptName
from professor, department
where department.chairman=professor.pID

// wrong ver
Select name, salary, department.deptName
from department, professor
where department.deptName = professor.deptName;

아래 두번째 wrong ver는 엉뚱한 '교수가 속한 학과'를 찾고있다.
. 다만, professor.deptName 속성값에 널 값이 존재할 수 있으며, 널 값을 가지는 터플은 조인이 되지 않아 결과 관계에 포함되지 않는다. 그러므로 두 번째 질의는 아래 질의와 동일하다.
Select name, salary, deptName
from professor
where deptName is not null;

  • List student names in a descending order of GPA (highest comes first)
select name
from student
order by GPA desc; 
profile
Sometimes you win, sometimes you learn 🏃‍♀️

0개의 댓글