2016-09-01 3 views
0
나는 다음과 같은 문제를 해결 할 방법

:오라클 SELECT (INTERSECT 대안)

우리가 약 100 온도 독자와 큰 건물이 있고 각각은 온도 분마다 수집 상상해보십시오.

내가

가 오히려 큰 테이블이 (~ 100m) 다음과 같은 열이있는 행 :

표 TempEvents :

Timestamp - one entry per minute 
Reader ID - about 100 separate readers 
Temperature - Integer (-40 -> +40) 

타임 스탬프 및 Reader ID는 테이블에 + 일차, 이차 키입니다. 나는 모든 타임 스탬프를 찾는 질의를 수행하고자합니다.
reader_01 = 10도,
reader_02 = 15도,
reader_03 = 20도입니다. 즉

이 같은 :

SELECT Timestamp FROM TempEvents 
WHERE (readerID=01 AND temperature=10) 
AND (readerID=02 AND temperature=15) 
AND (readerID=03 AND temperature=20) 

==> 타임 스탬프의 목록 결과 :

Timestamp:: 
2016-01-01 05:45:00 
2016-02-01 07:23:00 
2016-03-01 11:56:00 
2016-04-01 23:21:00 

위의 쿼리가 하나의 행에서 모든 조건을 포함하지 않기 때문에 아무 것도 반환하지 않습니다 일단. 모든 판독기가 조건과 일치해야하므로 조건 사이에 OR을 사용하면 원하는 결과가 생성되지 않습니다.

INTERSECT를 사용하여, 나는하여 결과를 얻을 수 있습니다

SELECT * FROM 
(SELECT Timestamp FROM TempEvents WHERE readerID=01 AND temperature=10 
INTERSECT SELECT Timestamp FROM TempEvents WHERE readerID=02 AND temperature=15 
INTERSECT SELECT Timestamp FROM TempEvents WHERE readerID=03 AND temperature=20 
) 
GROUP BY Timestamp ORDER BY Timestamp ASC; 

위의 쿼리가 매우 비용이 많이 드는하고 실행하는 데 약 5 분 정도 소요됩니다.

결과를 얻는 더 좋은 (더 빠른) 방법이 있습니까?

+3

SELECT 소인 TempEvents FROM WHERE (readerID = 01, 온도 = 10) OR (readerID = 02, 온도 = 15) OR (readerID = 03, 온도 = 20)? – neutrino

+1

있는지,하지만 약되지 않음 : 'TempEvents readerid에 의해 ((1,10), (2,15), (3,20)) 그룹 (readerid, 온도), 온도 가진 계수로부터 타임 스탬프 을 선택 (distinct readerid) = 3;' –

+1

위의 문제에 대해 솔직히 말해서 가장 간단한 것은 @neutrino가 제안한 것입니다.그의 솔루션을 사용하면서 얻는 문제점은 무엇입니까 – XING

답변

0

괄호 밖에서하는이 시도 : 아마도이

with Q(readerID,temperature) as(
select 01, 10 from dual 
union all 
select 02,15 from dual 
union all 
select 03,20 from dual 
) 
select Timestamp FROM TempEvents T, Q 
where T.readerID=Q.readerID and T.temperature=Q.temperature 
group by Timestamp 
having count(1)=(select count(1) from Q) 

OR 또는 IN 절을 사용하는 것보다 더 좋은 계획을 제공 할 것입니다.

+0

Mike에게 감사드립니다. 나는 이것을 시도했지만, 교차 대안을 사용하여 43 초에 비해 9 초 밖에 걸리지 않았습니다. 대단한 개선 !!!! – HHansson

0

당신이 쿼리에있는 독자의 수는

select distinct Timestamp 
    from TempEvents t1 
    join TempEvents t2 using(Timestamp) 
    join TempEvents t3 using(Timestamp) 
where t1.readerID=01 and t1.temperature = 10 
    and t2.readerID=02 and t2.temperature = 15 
    and t3.readerID=03 and t3.temperature = 20 

같은 join - 쿼리를 사용하여 시도 할 수 있습니다하지만 그것은 당신의 INTERSECT - 쿼리보다 더 나은 수행합니다 의심 솔직히 너무 큰되지 않습니다.

1

난 그냥 오라클 DB에서 이것을 시도하고 작동하는 것 같다 :

SELECT Timestamp FROM TempEvents 
WHERE (readerID=01 AND temperature=10) 
OR (readerID=02 AND temperature=15) 
OR (readerID=03 AND temperature=20) 

하면 변경에만 있는지 확인하고

+0

"AND"를 모방하는 표현식과 having 절로 그룹이 누락되었습니다. – Nemeros