다음 문제를 풀어보세요.


17.70 트랜잭션 T1, T2, T3에 대하여 스케줄 s1, s2 중에서 충돌 직렬 가능한 (conflict serializable) 것은?


T1: r1(x); r1(z); w1(x);

T2: r2(z); r2(y); w2(z);

T3: r3(x); r3(y); w3(y);


s1: r1(x); r2(z); r1(z); r3(x); r3(y); w1(x); w3(y); r2(y); w2(z);

s2: r1(x); r2(z); r3(x); r1(z); r2(y); r3(y); w1(x); w2(z); w3(y);



1. s1  

2. s2  

3. s1, s2  

4. 없음




충돌직렬(Conflict serializability)


충돌직렬가능성의 정의는 아래와 같습니다.


동일한 데이터 Q에 대해 접근하는 트랜잭션 Ti, Tj의 내부의 연속적인 연산이 Ii, Ij일 경우


Ii = read(Q), Ij = read(Q) : 비충돌

Ii = read(Q), Ij = write(Q) : 충돌

Ii = write(Q), Ij = read(Q) : 충돌

Ii = write(Q), Ij = write(Q) : 충돌


즉, 서로 다른 트랜잭션에서 동일한 자원에 대해 연속적으로 읽기 / 읽기를 제외한 쓰기(write)가 하나라도 발생하면 충돌입니다. (읽기/쓰기, 쓰기/읽기, 쓰기/쓰기) 이런 충돌이 순환 사이클을 그리는 경우을 말합니다.




낮은 단계(하위 수준) 고립성 수준에서 발생하는 현상들


부정판독(Dirty Read)


다른 트랜잭션에 의해 커밋(commit)되지 않은 수정된 데이터를 참조하는 것을 의미한다. 수정을 가한 트랜잭션이 롤백(Rollback)되면 그 데이터를 참조한 트랜잭션은 일관되지 않은 상태에 놓이게 된다.



비반복 가능 판독(Non-Repeatable Reads)


한 트랜잭션에서 같은 데이터를 두번 이상 읽을 때, 그 중간에 다른 트랜잭션이 값을 갱신하거나 삭제함으로 읽은 값들이 서로 다르게 되는 현상이다.



팬텀판독(Phantom Read)


한 트랜잭션에서 같은 데이터를 두번 이상 읽을때, 그 중간에 다른 트랜잭션이 값을 추가함으로써 처음 데이터를 읽을때 없던 유령(Phantom) 레코드가 나타나는 현상이다. 

 




트랜잭션 고립성 수준(Transaction Isolation Level) - ANSI/ISO SQL 표준으로 정의



판독 비완료(Read Uncommitted)


커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용한다.



판독 완료(Read Committed)


트랜잭션이 커밋되어 완료된 데이터만 다른 트랜잭션이 읽도록 허용함으로써 부정판독(Dirty Read)를 방지해 준다.


반복 가능 판독(Repeatable Read)


오직 완료된 레코드만이 읽혀질 수 있으며, 같은 레코드의 반복적인 판독은 동일한 값을 반환한다. 즉, 첫번째 있던 레코드가 삭제되거나 값이 갱신되는 현상을 방지함으로써 비반복 가능판독(Non-Repeatable Read)를 방지해 준다.


직렬 가능(Serializable)


오직 완료된 레코드만이 읽혀질 수 있으며, 같은 레코드의 반복적인 판독은 동일한 값을 반환한다. 즉, 첫번째 있던 레코드가 삭제되거나 값이 갱신되는 현상을 방지함으로써 비반복 가능판독(Non-Repeatable Read)를 방지해 준다. 또한 새로운 레코드가 나타나지도 않음으로써, 팬텀 판독(Phantom Read)도 방지해 준다.


 

감리사문제)

SQL 1992(SQL2) 4가지 격리 수준(isolation level) 중에서 한 트랜잭션 내에서 동일한 데이터를 두 번 읽을 때서로 다른 값을 읽는 경우가 발생할 수 있는 격리 수준을 모두 고르시오. (2개 선택)


1. Read committed            

2. Serializable     

3. Repeatable read           

4. Read uncommitted




다음 문제를 풀어보세요.


17.69. 사용자 U1이 생성한 EMPLOYEE(Eno, Name, Salary) 테이블에 대해 다음의 SQL 명령을 순서대로 실행할 때, 권한 부여 에러가 발생하는 위치를 모두 모아놓은 것은?


 1

 U1: GRANT INSERT, DELETE ON EMPLOYEE TO U2;

 2

 U1: GRANT SELECT ON EMPLOYEE TO U3 WITH GRANT OPTION;

 3

 U2: GRANT INSERT ON EMPLOYEE TO U4;

 4

 U3: GRANT SELECT ON EMPLOYEE TO U5;

 5

 U5: GRANT SELECT ON EMPLOYEE TO U6;

 6

 U1: GRANT SELECT ON EMPLOYEE TO U6;

 7

 U1: REVOKE SELECT ON EMPLOYEE FROM U3;

 8

 U6: SELECT * FROM EMPLOYEE;

 9

 U5: SELECT * FROM EMPLOYEE;

 10

 U6: UPDATE EMPLOYEE SET Salary = Salary * 1.1;


1. 2, 3, 5

2. 3, 5, 10

3. 3, 5, 9, 10

4. 3, 5, 8, 9, 10



[풀이]


1. U1 → U2 (INSERT/DELETE)

2. U1 → U3 (SELECT) GRANT OPTION

3. U2 → U4 (INSERT) : [ERROR] 권한없음

4. U3 → U5 (SELECT)

5. U5 → U6 (SELECT) : [ERROR] 권한없음

6. U1 → U6 (SELECT)

7. U1 → U3 (SELECT) REVOKE

8. U6 

9. U5

10. U6 (UPDATE)  : [ERROR] 권한없음




다음 문제를 풀어보세요.


17.68. 질의 최적화 기법에 대한 설명으로 틀린 것은?


1. 주기억장치보다 더 큰 용량의 데이터에 대하여 SQL의 order by 절을 수행하기 위해서는 정렬-합병 전략의 외부 정렬을 수행해야 한다.


2. 관계대수의 실렉트 연산을 수행하기 위해서는 데이터베이스 전체를 읽어들이는 파일 스캔 탐색이나 인덱스를 활용한 인덱스 스캔 탐색을 수행한다.


3. 두 릴레이션 R과 S에 대하여 조인 연산을 수행할 때, R과 S의 레코드들이 조인 애트리뷰트 A와 B값에 물리적으로 정렬되어 있으면 분할-해시 조인이 가장 효율적으로 구현될 수 있다.


4. 외부 조인은 중첩 루프 조인이나 단일 루프 조인 알고리즘 중 하나를 수정하여 구현할 수 있다.



내부정렬과 외부정렬



○ 내부정렬 (internal sorting)


→ 데이터가 적어서 메인 메모리 내에 모두 저장시켜 정렬 가능할 때 사용함

→ 레코드의 판독(read)및 기록(write)에 걸리는 시간이 문제가 되지 않음



○ 외부정렬 (external sorting)


→ 데이터가 많아서 메인 메모리의 용량을 초과하여 보조기억장치(디스크, 테이프)에 저장된 파일을 정렬할 때 사용함

 레코드 판독 및 기록에 걸리는 시간이 중요한 요소임

 정렬/합병 (sort/merge)




조인 방식



○ 중첩반복 (Nested Loops) 조인


프로그래밍의 중첩 반복문과 유사한 방식으로 조인을 수행한다.


FOR 선행 테이블 읽음 -> 외부 테이블

FOR 후행 테이블 읽음 -> 내부 테이블

(선행 테이블과 후행 테이블 조인)


→ 동작 방법

1. 선행 테이블에서 주어진 조건을 만족하는 행을 찾음

2. 선행 테이블의 조인 키 값을 가지고 후행 테이블에서 조인 수행

3. 선행 테이블의 조건을 만족하는 모든 행에 대해 1번 작업 반복 수행



○ 정렬병합 (Sort Merge) 조인


조인 컬럼을 기준으로 데이터를 정렬하여 조인을 수행한다. 


→ 동작 방법

1. 선행 테이블에서 주어진 조건에 만족하는 행을 찾음

2. 선행 테이블의 조인 키를 기준으로 정렬 작업을 수행

3. 1~2번 작업을 선행 테이블의 조건을 만족하는 모든 행에 대해 반복 수행

4. 후행 테이블에서 주어진 조건에 만족하는 행을 찾음

5. 후행 테이블의 조인 키를 기준으로 정렬 작업을 수행

6. 3~4번 작업을 선행 테이블의 조건을 만족하는 모든 행에 대해 반복 수행

7. 정렬된 결과를 이용하여 조인을 수행하며 조인에 성공하면 추출버퍼에 넣음


Sort Merge Join은 대량의 정렬작업이 필요로 하므로 Hash Join이 성능상 더 유리하다고 한다.



○ 해시(Hash) 조인


해싱기법을 이용하여 조인을 수행한다. 


→ 동작 방법

1. 선행 테이블에서 주어진 조건을 만족하는 행을 찾음

2. 선행 테이블의 조인키를 기준으로 해쉬 함수를 적용하여 해쉬 테이블을 생성

3. 1~2번 작업을 선행 테이블의 조건을 만족하는 모든 행에 대해 반복 수행

4. 후행 테이블에서 주어진 조건을 만족하는 행을 찾음

5. 후행 테이블의 조인키를 기준으로 해쉬 함수를 적용하여 해당 버킷을 찾음 (조인키를 이용하여 실제 조인될 데이터를 찾음)

6. 조인에 성공하면 추출버퍼에 넣음

7. 3~5번 작업을 후행 테이블의 조건을 만족하는 모든 행에 대해서 반복 수행


Hash Join은 작은 테이블을 선행 테이블로 사용하는 것이 성능 관점에서 좋다고 한다. 

Hash Join은 해싱 함수의 특성상 동등 조인에만 사용할 수 있다.



다음 문제를 풀어보세요.


17.67. 물리적 데이테베이스 설계 단계에서 색인 구조를 결정하는데 도움이 되는 지침으로 틀린것은?


1. 한 애트리뷰트에 들어 있는 상이한 값들의 개수가 전체 레코드의 수와 비슷하고 검색에서 해당 애트리뷰트에 대한 동등 조건이 사용된다면 비 클러스터링(non-clustering) 색인을 생성하는 것이 좋다.


2. 갱신이 빈번하게 이루어지는 릴레이션에 대해서 색인을 많이 생성하여 갱신의 효율성을 증진할 수 있다.


3. 가능하면 정수형 애트리뷰트에 색인을 만드는 것이 좋고 반대로 VARCHAR 데이터 타입을 갖는 애트리뷰트에는 색인을 만드는 것을 피해야 한다.


4. 대량의 데이터를 사입할 때는 모든 색인들을 제거하고 데이터 삽입이 끝난 후에 색인들을 다시 생성하는 것이 효율적이다.



 

쿼리(Query) 종류


포인트쿼리 (Point query) 


조회되는 데이터가 한두개

select * from member where id='ryu'


범위쿼리 (Range query)
 

조회되는 데이터가 다수 
select * from member where date='2008/06/19'


커버드쿼리 (Covered query)

조회의 대상과 조회의 결과가 컬럼이 일치하는 상태. 인덱스 측면에서 제일 빠른 성능을 냄


Point query : select * from member where id='ryu' and pw='1234'

Covered query: select id from member where id='ryu' and pw='1234'




인덱스의 개념


인덱스는 데이터를 찾을 때(SELECT) 때 빨리 찾기 위해서 사용한다. 인덱스가 없다면 특정한 값을 찾기 위해 모든 데이터 페이지를 다 뒤져야 한다. 이것을 Table Scan 이라고 한다. 인덱스가 찾고자 하는 컬럼이나 표현식에 대해 존재하고, 인덱스를 사용하는 것이 더 효과적이라면, SQL 서버는 모든 페이지를 뒤지지 않고 인덱스 페이지를 찾아서 쉽게 데이터를 가져온다. 이것을 Index Seek라고 한다.

 인덱스의 단점

- 만드는데 시간이 걸린다.

- 만드는데 많은 공간이 필요하고, 만들고 난 후에도 추가적인 공간이 필요하다.

- 데이터를 수정(INSERT, UPDATE, DELETE)하는 시간, 특히 INSERT 작업은 오히려 더 많이 걸린다.


☞ 인덱스를 걸어야 할 컬럼

- WHERE 절에서 자주 사용되는 컬럼

- 자주 검색되는 컬럼(SELECT 절에서)

- 기본 키는 자동적으로 클러스터 인덱스가 만들어 진다.

- 참조 키(Foreign Key)에 인덱스를 걸면 조인 사용할 때에 조인의 속도를 향상시킨다. 색인이 자동적으로 만들어지지 않는다.

- 자주 JOIN으로 사용하는 컬럼(참조 키가 아닐 때)

- 정렬된 순서로 자주 사용되는 컬럼(가능하다면 클러스터 인덱스를 만드는 것이 좋다)

- 범위를 주고 찾는 컬럼(가능하다면 클러스터 인덱스를 만드는 것이 좋다)


인덱스를 걸지 않아야 할 컬럼

- 좀처럼 검색되지 않는 컬럼

- 전체 중 상당 부분을 가져오는 질의에 사용되는 컬럼

- 유일성, 또는 같은 값이 많은 컬럼

SELECT 속도보다 데이터의 변경 속도가 훨씬 중요할 때(되도록 색인의 수를 최소화 한다.)




인덱스의 종류


클러스터 인덱스 (Clustered Index)


① 테이블마다 단 한개의 클러스터 인덱스가 존재한다. 
② 물리적인 행(데이터)의 순서가 인덱스의 순서와 동일하다.
③ 인덱스의 맨 마지막 단계인 리프 레벨(Leaf Level)이 곧 데이터 페이지이다.
④ 실제 데이터의 순서와 인덱스의 순서가 일치하기 때문에 일정한 범위를 주고 찾는 경우 속도 향상에 도움이 된다.
⑤ Non-Clustered Index에 비해 색인의 단계가 한 단계 적기 때문에 색인의 크기도 작고 그만큼 빨리 찾을 수 있다.
⑥ 새로운 데이터가 입력되면 항상 물리적 순서를 색인의 순서에 맞추어야 하기 때문에 많은 데이터가 자신의 자리를 찾는 작업을 해야 하므로 이 부분에서는 오히려 넌클러스터드 인덱스보다 느리다.


넌-클러스터 인덱스 (Non-Clustered Index)

① 물리적인 행의 순서가 색인의 순서와 동일하지 않다. 

② 리프 레벨은 데이터 페이지가 아니다.

③ 리프 레벨에서 한 단계 더 내려가야만 데이터 페이지이다. 따라서 클러스터 색인보다 한 단계를 더 거쳐야 실제 찾고자 하는 데이터에 도달할 수 있다.

'정보시시스템감리사 > 데이터베이스' 카테고리의 다른 글

권한부여 (GRANT, REMOKE)  (0) 2017.09.07
질의 최적화 기법  (0) 2017.09.01
조인 선택률(join selectivity)  (0) 2017.08.31
데이터 마이닝 분석기법 종류  (0) 2017.08.29
교착상태 (deadlock)  (0) 2017.08.29


다음 문제를 풀어보세요.


17.66 다음 두 릴레이션 R과 S에 대해 조인 연산을 수행했다고 할 때, 이 연산의 조인 선택률(join selectivity)은?


그림 삽입 예정


1. 1

2. 4/9

3. 5/9

4. 5



선택률(selectivity)


(조건을 만족하는 투플수) / (릴레이션의 전체 투플수)



다음 문제를 풀어보세요.


데이터 마이닝 분석기법과 관련된 이론을 가장 적절하게 연결한 것은?


1. 지지도(support) - 인공신경망

2. 시그모이드(sigmoid) 함수 - 의사결정트리

3. 맨하튼 거리(manhattan distance) - 군집분석

4. 엔트로피(entropy) - 연관분석



데이터 마이닝의 기법


① 의사결정나무 (Decision Tree)

주어진 데이터를 분류(Classification) 하는 목적으로 사용된다. 예측(Prediction)하는 목적으로 사용할 수 없다.


 인공신경망 (Artificial Neural Network)

자신이 가진 데이터로부터 반복적인 학습 과정을 거쳐 패턴을 찾아내고 이를 일반화함으로써 예측(Prediction) 가능한 기법


 연관성 규칙 발견 (Association Rule Discovery)

상품 혹은 서비스간의 관계를 살펴보고 이로부터 유용한 규칙을 찾아내고자 할 때 이용될 수 있는 기법이다. 상품간의 연관성 정도를 측정하여 관성이 많은 상품들을 그룹화하는 클러스터링(clustering)의 일종


 사례 기반 추론 

사례기반 추론 기법(CBR)은 한마디로 주어진 새로운 문제를 과거의 유사한 사례를 바탕으로 주어진 문제의 상황에 맞게 응용하여 해결해 가는 기법을 말한다.


 군집분석

대용량의 데이터가 너무 복잡할 때는 이를 구성하고 있는 몇개의 군집을 나누어 살펴봄으로써 전체에 대한 윤곽을 잡을수 있다. 










다음 문제를 풀어보세요.


트랜잭션 T1은 x와 y에 100을 더하고, 트랜잭션 T2는 y와 x에 2를 곱하는 트랜잭션이다. 두 트랜잭션이 다음과 같은 순서로 실행이 되었을 때 발생한 상황은?


시간1: T1 lock(x); read(x);

시간2: T2 lock(y); read(y);

시간3: T1 x = x + 100

시간4: T2 y = y * 2

시간5: T1 write(x)

시간6: T2 write(y)

시간7: T1 lock(y)

시간8: T2 lock(x)


1. 갱신 손실(lost update)

2. 교착 상태(deadlock)

3. 오손 읽기(dirty read)

4. 철회(rollback)




다음 문제를 풀어보세요.


트랜잭션 T1, T2가 수행되는 다음 그림에서 T1의 연산결과(x+100)가 T2의 연산결과(x*2)로 인해 바르게 저장되지 않는 현상이 발생할 수 있다. 이 같은 현상을 무엇이라고 하는가?



1. 갱신 손실(lost update)

2. 오손 읽기(dirty read)

3. 지연 갱신(deferred update)

4. 갱신 충돌(update conflict)




트랜잭션 격리성 수준 (Transaction Isolation Level)


Isolation Level 

Dirty Read 

Non Repeatable Read 

Phantom Read 

 Read Uncommitted

Permitted 

Permitted 

Permitted 

 Read Committed

---

 Permitted

 Permitted

 Repeatable Read

---

---

 Permitted

 Serializable

---

---

---



Level - 0 ( = Read Uncommitted)


① 커밋되지 않은 데이터를 다른 트랜잭션에서 읽는 것을 허용

② Dirty Read, Non-Repeatable Read, Phantom Read 현상 발생


Dirty Read

다른 트랜잭션에 의해 수정되었지만 아직 커밋되지 않은 데이터를 읽는것을 의미한다. 커밋되지 않은 값을 읽었는데, 그 트랜잭션이 롤백(Rollback) 된다면 그 값을 읽은 트랜잭션은 비일관된 상태에 놓이게 된다.


Phantom Read

한 트랜잭션 내에서 같은 쿼리를 두번 수행했는데, 첫번째 쿼리에는 없던 유령(Phantom) 레코드가 두번째 쿼리에서 나타나는 현상을 말한다.



Level - 1 ( = Read Committed)


① 트랜잭션이 커밋되어 확정된 데이터만 읽는 것을 허용함으로써 Dirty Read를 방지해줌

② Non-Repeatable Read, Phantom Read 현상 발생



Level - 2 ( = Repeatable Read)


① 트랜잭션 내에서 쿼리를 두번 이상 수행할 때, 첫번째 쿼리에 있던 레코드가 사라지거나 값이 바뀌는 현상을 방지해 줌.

② Phantom Read 현상은 발생



Level - 3 ( = Serializable Read)


① 트랜잭션 내에서 쿼리를 두번 이상 수행할 때, 첫번째 쿼리에 있던 레코드가 사라지거나 값이 바뀌지 않음은 물론 새로운 레코드가 나타나지도 않음.

② 완벽한 일관성 제공






다음 문제를 풀어보세요.


인덱스의 생성 여부를 결정하기 위해 고려할 사항에 대한 설명이 잘못된 것은? (2개 선택)


1. 유일한키 속성에 대해서는 인덱스를 생성한다.

2. 실렉션 조건이나 조인 조건에서 사용되는 속성에 대해서는 인덱스를 생성한다.

3. 인덱스 탐색만을 통해 답변이 가능한 질의에 대해서는 클러스터 인덱스를 고려한다.

4. 동등 조건과 범위 질의에 사용되는 속성에 대해서는 해시 인덱스가 유리하다.



해시(Hash) 인덱스


해시 인덱스는 B-Tree만큼 범용적이지 않지만 고유의 특성과 용도를 지닌 인덱스 가운데 하나이다. 해시 인덱스는 동등 비교 검색에는 최적화되어 있지만 범위를 검색한다거나 정렬된 결과를 가져오는 목적으로는 사용할 수 없다.


해시 인덱스는 메모리 기반의 테이블에 주로 구현돼 있으며 디스크 기반의 대용량 테이블용으로는 거의 사용되지 않는다는 특징이 있다.



클러스터드 인덱스(Clustered Index)와 넌클러스터드 인덱스(Non-Clustered Index)


클러스터드 인덱스는 물리적으로 행을 재배열한다. 원래의 경우 데이터가 삽입되는 순서대로 물리적으로 저장되는데, 클러스터드 인덱스는 삽입되는 순서에 상관없이 인덱스로 생성되어 있는 컬럼(들)을 기준으로 정렬된 후에 파일에 저장된다.


넌클러스터드 인덱스는 우리가 알고 있는 인덱스를 말한다. 데이터가 입력되는 순서대로 파일에 저장되고, 인덱스를 만들어서 물리적인 위치의 데이터에 접근한다.



다음 문제를 풀어보세요.


EMPLOYEE(Eno, Name, DeptName, Salary) 테이블에 대해 "평균 봉급이 가장 높은 부서명(DeptName)을 검색" 하는 질의를 다음과 같이 작성한다고 할 때, 밑줄 친 부분에 들어갈 내용으로 맞는 것은?



SELECT DeptName

FROM EMPLOYEE

GROUP BY DeptName

(㉠) >= () (SELECT AVG(Salary) FROM EMPLOYEE () DeptName);


1. WHERE Salary, all, ORDER BY

2. WHERE AVG(Salary), some, GROUP BY

3. HAVING Salary, some, ORDER BY

4. HAVING AVG(Salary), all, GROUP BY



하위 쿼리를 시작하는 비교 연산자는 ALL 또는 ANY 키워드에 의해 수정될 수 있습니다. SOME은 ANY의 ISO 표준 동의어입니다.

수정된 비교 연산자로 시작하는 하위 쿼리는 0개 이상의 값 목록을 반환하고 GROUP BY나 HAVING 절을 포함할 수 있습니다. 이러한 하위 쿼리는 EXISTS를 사용하여 다시 작성할 수 있습니다.

> 비교 연산자를 예로 들면 >ALL은 모든 값보다 크다는 것을 의미합니다. 즉, 최대값보다 크다는 것을 나타냅니다. 예를 들어 >ALL (1, 2, 3)은 3보다 크다는 것을 의미합니다. >ANY는 적어도 하나의 값보다 큼 즉, 최소값보다 크다는 것을 의미합니다. 따라서 >ANY (1, 2, 3)은 1보다 큼을 의미합니다.

>ALL이 있는 하위 쿼리의 행이 외부 쿼리에 지정된 조건을 만족시키려면 하위 쿼리를 시작하는 열의 값이 하위 쿼리에서 반환되는 값 목록의 모든 값보다 커야 합니다.

마찬가지로 >ANY가 있는 행이 외부 쿼리에 지정된 조건을 만족시키려면 하위 쿼리를 시작하는 열의 값이 하위 쿼리에서 반환되는 값 목록에서 하나 이상의 값보다 커야 합니다.

다음은 ANY로 수정된 비교 연산자로 시작하는 하위 쿼리를 보여 주는 예입니다. 이 쿼리에서는 가격이 제품 하위 범주의 최대 가격보다 크거나 동일한 제품을 찾습니다.

USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE ListPrice >= ANY
    (SELECT MAX (ListPrice)
     FROM Production.Product
     GROUP BY ProductSubcategoryID) ;

각각의 Product 하위 범주마다 내부 쿼리는 최대 가격을 찾습니다. 외부 쿼리는 이러한 값 모두를 찾고 Product 하위 범주의 최대 가격보다 크거나 동일한 개별 제품의 가격을 확인합니다. ANY를 ALL로 변경하면 가격이 내부 쿼리에서 반환된 모든 가격보다 크거나 동일한 제품만 반환됩니다.

하위 쿼리에서 반환된 값이 없으면 전체 쿼리에도 반환 값이 없습니다.

=ANY 연산자는 IN과 동일합니다. 예를 들어 IN 또는 =ANY를 사용하여 Adventure Works Cycles에서 만드는 모든 바퀴 제품의 이름을 찾을 수 있습니다.

--Using =ANY
USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE ProductSubcategoryID =ANY
    (SELECT ProductSubcategoryID
     FROM Production.ProductSubcategory
     WHERE Name = 'Wheels') ;

--Using IN
USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE ProductSubcategoryID IN
    (SELECT ProductSubcategoryID
     FROM Production.ProductSubcategory
     WHERE Name = 'Wheels') ;

각 쿼리의 결과 집합은 다음과 같습니다.

Name
--------------------------------------------------
LL Mountain Front Wheel
ML Mountain Front Wheel
HL Mountain Front Wheel
LL Road Front Wheel
ML Road Front Wheel
HL Road Front Wheel
Touring Front Wheel
LL Mountain Rear Wheel
ML Mountain Rear Wheel
HL Mountain Rear Wheel
LL Road Rear Wheel
ML Road Rear Wheel
HL Road Rear Wheel
Touring Rear Wheel

(14 row(s) affected)

그러나 < >ANY 연산자는 NOT IN과는 다릅니다. < >ANY는 not = a, or not = b, or not = c를 의미하지만 NOT IN은 not = a, and not = b, and not = c를 의미합니다. <>ALL은 NOT IN과 동일한 의미입니다.

예를 들어 다음 쿼리는 영업 직원이 담당하지 않는 지역에 있는 고객을 찾습니다.

Use AdventureWorks2008R2;
GO
SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID <> ANY
    (SELECT TerritoryID
     FROM Sales.SalesPerson) ;

고객에게 할당된 모든 지역을 영업 직원이 담당하기 때문에 결과에는 영업 지역이 NULL인 고객을 제외한 모든 고객이 포함됩니다. 내부 쿼리가 영업 직원의 담당 영업 지역을 모두 찾은 후 외부 쿼리가 각 지역마다 해당 지역에 없는 고객을 찾습니다.

이와 같은 이유로 이 쿼리에서 NOT IN을 사용하면 결과에 아무 고객도 포함되지 않습니다.

NOT IN에 해당하는 < >ALL 연산자를 사용해도 동일한 결과를 얻을 수 있습니다.

+ Recent posts