2016-09-01 10 views
0
私は次のような問題を解決するにはどうすればよい

OracleのSELECT(INTERSECTの選択肢は)

たちは、約100の温度リーダーとの大きな建物があり、それぞれが温度毎分を収集想像してみてください。

私は、次の列ではなく、大規模なテーブル(〜100メートル)の行があります。

表のTempEvents:

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

タイムスタンプおよびReader IDはテーブルに二+主キーです。
reader_01 = 10度、
reader_02 = 15度、
_read_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タイムスタンプFROM TempEvents ここで(readerID = 01 AND temperature = 10) OR(readerID = 02 AND temperature = 15) OR(readerID = 03 AND temperature = 20)? – neutrino

+1

わかりませんが、何について: 'SELECT Timestamp FROM TempEvents WHERE(readerid、temperature)IN((1,10)、(2,15)、(3,20)) グループby readerid、温度 count (別個のリーダーID)= 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秒でした。大きな改善!!!! – 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 -queryを使用してみてくださいしかし、私はそれがあなたのINTERSECT -queryよりも良好に機能します疑う正直に言うとあまり大きくない場合。

1

私はOracleの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"を模倣するための式と句を持つグループがありません – Nemeros

関連する問題