2017-11-16 1 views
1

두 개의 열이 idval 인 테이블이 있다고 가정합니다. 나는 똑같은 반대의 쌍인 val이 존재하는 모든 구별 id을 찾지 않을 것이다. 예를 들어 값을 5, -56, -6이 있기 때문에 결과가 결과에등가 및 반대 값에 대한 SQL 문의

result 
    2 
    3 

2 설정으로 내가 원하는 다음 표

id | val 
------+------ 
    1 | 3 
    2 | 5 
    2 | -5 
    1 | 4 
    2 | 6 
    3 | 9 
    2 | -6 
    3 | -9 

이 있다고 가정합니다. 9, -9 때문에 3이 결과 집합에 있습니다.

where exists을 사용하여이 작업을 수행 할 수 있습니다.

select distinct tab1.id from tab tab1 
where exists (
    select * from tab tab2 
    where tab1.id = tab2.id 
    and tab1.val = -tab2.val 
); 

같은 뭔가 내가이 중첩 루프처럼 계산하기 때문에이 같은 쿼리가 시간 복잡도 O(n^2)을 가지고 걱정하지만 (?). 그러나 테이블을 스캔하여 (그리고 O(1) 검색 시간을 가진 데이터 구조에서 이전에 본 결과를 추적하여) O(n) 시간에 이것을 계산할 수 있습니다. 그러한 쿼리를 작성하는 최적의 방법은 무엇입니까?

+0

성능을 고려하기 전에 쿼리 계획을 확인하고 게시하십시오. –

+1

여기에 중첩 루프가 표시되지 않습니다. 아마도 약간의 데카르트 제품 종류의 상황이지만, 끔찍한 것은 아닙니다. 이것은 INNER JOIN과 비슷한 훌륭한 서브 쿼리를 닮았습니다 (이 상황에서도 작동 할 것입니다) – JNevill

답변

0

요청에 대한 설명과 색인 설정 방법을 알려주십시오.

은 너무과 같이 할 수 있습니다 될 수있다

바로 연동제와
WITH pos AS (
    SELECT id, val FROM tab WHERE val > 0), 
neg AS (
    SELECT id, val FROM tab WHERE val < 0) 
SELECT DISTINCT id 
    FROM pos JOIN neg USING (id) 
WHERE pos.val = neg.val; 

이 빠른 수 있습니다. 또한 데이터 양에 의존하십시오.