DB/관계형 DB

Select

쿠와와 2021. 1. 22. 17:21

Select = 데이터를 얻을 수 있는 유일한 수단 

 

기본 구조 

SELECT 칼럼의 목록
FROM 테이블의 목록
WHERE 검색 조건 

칼럼의 목록 = Projection

데이블의 목록 = Product

검색 조건 = Restrict

 

-> 평가 순서가 있음 (유의하자) 평가 순서 != 실행 순서 

1. 테이블의 목록

2. 검색 조건

3. 컬럼의 목록 

 

 

집계함수 

함수의 유무만으로 의미가 봐뀜 

구문이 완전히 같아도 SELECT의 칼럼의 목록 (select list) 중에 집계함수가 포함돼 있으면 select의 결과 전체가 집계결과가 된다. 

 

집계 함수 없음

SELECT CONCAT(name, ':', department)
FROM studunts
WHERE department = '관계형 모델'

-> 학생의 수만 포함 

집계 함수 

SELECT CONCAT( * )
FROM studunts
WHERE department = '관계형 모델'

-> 결과 집합에 행이 한개가 됨

 

COUNT의 특수성 

count는 일치하는 행이 존재하지 않으면 결과는 0이 된다. 이 같은 결과는 다른 집계함수에서는 같지만, count만 '공집합을 평가한 결과가 0이 된다'라는 동작을 한다. 그 외의 집계함수 평가는 공집합에 대해 null이 된다. 

 

즉 null값을 카운트에서는 신경쓸 필요없다.

 

GROUP BY

특정 항목별로 집계하고 싶을 때 사용 

SELECT department, COUNT(*)
FROM students
GROUP BY department
HAVING COUNT(*) <= 30

=> 소속 인원이 30명 이하인 학생의 수 집계

 

WHERE = 집계의 대상의 되는 행의 조건 -> 이 때 group by 결과에 where 조건에 해당하는 행이 없으면 결과 표시 x 

HAVING = 집계된 결과에 대한 조건 

ORDER BY = ()안의 조건으로 정렬 (기본적으로는 오름차순)

 

이 때 GROUP BY, HAVING, ORDER BY 순으로 써야 한다. 

 

 

서브쿼리

외형은 모두 select지만 서브쿼리의 결과는 스칼라, 행, 테이블과 같은 형태로 자유롭게 변할 수 있다. 어떤 유형의 서브쿼리가 될지는 서브쿼리의 결과에 포함된 열의 수, 행의 수에 따라 결정된다. 

 

테이블 서브쿼리

서브쿼리의 결과가 테이블의 형태로 세 가지의 종류가 있다. 

1. IN, ANY, ALL : 대부분의 서브쿼리의 결과가 한 열이 되지만, 여러 칼럼을 한 번에 비교할 수 있다.

 

2. FROM 절의 서브쿼리 (Subquery in the FROM Clause). 서브쿼리의 결과를 FROM 절에서 일반 테이블처럼 다루고 SELECT에 따라서 추가 연산을 수행하거나 다른 테이블과 JOIN 하는 식으로 사용한다. 

 

3. EXISTS 서브 쿼리 : 평가되는 것은 서브쿼리를 평가한 결과, 행이 한 개라도 존재하는지 아닌지에 대한 것 ( 보통 WHERE문에 사용되지만 HAVING, select list 에 사용되기도 한다. )

 

스칼라 서브쿼리 

서브쿼리의 결과가 스칼라(1행 1열)여야 한다. 

WHERE, HAVING 에서 스칼라 값과 비교하거나 select list에서 스칼라값을 구하는데 사용된다. 

WHERE 절의 서브 쿼리 
SELECT name, age
FROM students s1 
WHERE age = (
  SELECT max(age)
  FROM students s2
)

HAVING 절의 서브쿼리
SELECT course, COUNT (*) AS COUNT
FROM course_reg
GROUP BY course
HAVING COUNT(*) > (
  SELECT AVG(c)
  FROM (
    SELECT COUNT (*) AS c
    GROUP BY course
  )
  AS t 
)

select list 내의 서브쿼리
SELECT (
  SELECT AVG(age) FROM students s
  WHERE s.department = d.department) 
AS age 
FROM department d

 

행 서브쿼리 

서브쿼리를 평가한 결과가 1행이고 열이 여러 개일때를 행 서브쿼리라고 부른다.

select list 내에 행 서브쿼리를 사용할 수 없다. (각 값이 스칼라여야 한다.) 

결과가 없을 때 NULL로 처리된다. 

 

UNION

SQL은 그 사양 상 결과 집합에 포함된 칼럼 수가 같다면 두 개의 SELECT를 UNION으로 더할 수 있다. 

여기서 주의할 점은 UNION으로 서로 더한 두 개의 SELECT는 다른 테이블을 참고하고 있거나 전혀 다른 실행 계획이 있다는 점이다. 

 

SELECT에서의 관계형 조작

릴레이션 연산 SELECT로 표현
제한 기본형 : WHERE 절
사영 기본형 : select list
곱집합 기본형 : FROM 절
결합 기본형 : FROM 절
기본형 : FROM 절
UNION
NOT EXIST 서브쿼리, MINUS
속성명 변경 기본형 : select list
확장 기본형 : select list

 

관계형이 아닌 조작 

관계형 모델에서 벗어나는 작업은 위험 요소가 있고 다루는 데 있어서 주의해야 한다.

 

정렬(sort) - 관계형 모델에서 각 요소에는 순서가 없다 (order by) 

 

명시적으로 정의되지 않은 칼럼 - ROWID, ROWNUM 같은 암묵적인 칼럼은 사용할 수 있지만 조심하자. 

 

스토어드 함수(사용자 정의 함수) - 절차형으로 처리될 수 있다. 이 경우 실행에 드는 비용을 예측할 수 없고 최적화할 수 없다. 즉 스토어드 함수가 포함된 쿼리는 실행 코스트가 높아지기 쉽다. 

 

이러한 조작들의 취급법 

-1. 관계형 모델의 범위에서 가능한 것은 절대로 관계형이 아닌 조작으로 구현하지 말자

-2. 관계형 모델의 범위에서 작성할 수 없다면 DB설계를 검토한다.

-3. 관계형 모델이 아닌 조작이 꼭 필요할 때는 관계형 조작에 대한 로직을 반드시 먼저 실시한다. 

 

옵티마이저 - 원래의 쿼리와 같은 결과를 얻을 수 있는 쿼리 중에서 최적의 실행 계획을 세운 것 또는 가장 실행 시간이 짧다고 생각되는 것을 선택하는 작업