본문 바로가기

Library/Database

Basic SQL

select 절은, 테이블에서 결과를 추출하기 위해서 사용된다(projection). 'select *' 형식으로 사용할 수도 있지만, 이것은 SQL 질의로 얻어진 결과를 명확하게 하지 않는다는 점에서 좋지않은 형식이다.

from 절은, 테이블 이름들의 리스트이며, 테이블 이름은 범위변수(Range Variable)에 의해서 표시될 수 있다. where 절의 qualification은 수식의 참 / 거짓 조건을 검사하여 일치하는 조건에 대해서만 결과물을 한정하게 된다.


SQL은 중첩된 형태로도 질의를 할 수 있다. 이런 형태는 from 절에서도 나타날 수 있지만, 일반적으로 where 절에 나타난다. 이런 중첩은 in 명령어를 사용하여 표현 가능하다. 어떻게 이런 중첩된 형태의 질의가 처리되는가? 이것은 in 연산자가, 어떤 값이 주어진집합에 속하는지 그렇지 않은지를 알려주기 때문에 그렇다. 다시 말해서, where S.sid in (select ...)와 같은 형식으로 SQL 질의가 주어졌다면, 부질의 안에서 어떤 조건을 검사하고, 이 집합에서 S.sid의 값이 존재하는지를 검사하여 최종적으로 true, false 여부를 판단하게 된다.

in 연산자와 비슷한 연산자로 exist 연산자가 있다. exist는 공집합과 암묵적인 비교연산자는, 집합이 공집합인지 아닌지를 검사한다. exist와 밀접하게 관련된 것으로 unique가 있다. unique를 부질의에 적용하면, 부질의의 답에 대해서 어떠한 행도 두번 나타나지 않으면 true, 중복이 있다면 false를 리턴한다.

집합 비교 연산자에 대해서 op-any, op-all 따위의 종류가 있다. op-any 형태에서 any 뒤의 부질의에서는, 이 부질의를 만족하는 어떤 튜플이 하나라도 존재하면, op와 연산되어 결과를 true, false로 리턴하게 된다. op-all 형태에서는, 부질의를 만족하는 튜플 전체에 대해서 op 연산자를 적용하여 결과를 리턴한다.

division은 SQL에서 어떻게 표현되는가? 먼저, cross-product는 두 테이블 사이에서 어떤 결과를 보여주는가? n, m 튜플을 가진 테이블에서 cross product의 결과는 n * m 크기의 테이블이다. 이것으로부터 division을 생각해본다면, Q × B = A일 때, 결과적으로 (A / B) * B = A가 항상 성립하는 것은 아니다. 즉, 여기서의 division은 일반적인 대수연산에서의 division과 의미적으로 완전히 동일한 것응 아니다. Q × B ⊆ A를 의미하는 것이 정확한 표현이다.

즉, division 연산 A / B는, B에 있는 모든 y 값에 대해서, A의 퓨플 < x, y >가 존재하는 단항 튜플 형태의 모든 x 값들의 집합으로 정의된다. 이것은, B 집합의 해당 원소가 하나일 경우 쉽게 이해되지만, 원소가 2개 이상이라면 혼랍스럽다. 예를 들어, A가 < x1, y1 >, < x1, y2 >, < x2, y1 >, < x2, y2 >< x3, y1 >의 원소를 가지고 있다고 했을 때, B < x1 >에 대한 A / B의 결과는 < y1, y2 >가 된다. 하지만, < x1, x2 >에 대한  A / B의 결과는 어떻게 되는가? 이 경우, < Q1, Q2 >의 Q1 × Q2의 결과가 A에 포함되어 있어야 한다. 즉, x1 × Q2, x2 × Q2가 A에 존재해야 하는데, division을 명확하게 정의하면 이것을 만족하는 x 값들의 집합이 A / B, 즉 Q1이 된다. 그렇다면, A / B는 직관적으로 무엇을 의미하는가? 이것은 B를 포함하는 A의 튜플을 의미한다고 볼 수 있을 것이다.