2011-12-08 8 views
3

SQLを使用して、1つのエントリと次のエントリの時間差に基づいて異なるデータエントリを選択しようとしています。これは一例で説明する方が簡単です:時間枠の外に別の行を選択

私のデータテーブルが

Part DateTime 
123  12:00:00 
123  12:00:05 
123  12:00:06 
456  12:10:23 
789  12:12:13 
123  12:14:32 

を持っている私がするのと同じ「パート」番号を持つ複数のエントリがある場合があることを制限している限り、すべての行を返したいです少なくとも5分の違いがあるものだけを検索するようにします。

クエリが返す必要があります:これは、残念ながら動作していない

SELECT data1.*, to_char(data1.scan_time, 'yyyymmdd hh24:mi:ss') 

FROM data data1 

where exists 
(
    select * 

    from data data2 

    where data1.part_serial_number = data2.part_serial_number AND 
    data2.scan_time + 5/1440 >= data1.scan_time 
    and data2.info is null 
) 

order by to_char(data1.scan_time, 'yyyymmdd hh24:mi:ss'), data1.part_serial_number 

Part DateTime 
123  12:00:00 
456  12:10:23 
789  12:12:13 
123  12:14:32 

私が使用しているコードは次のようです。誰かが私が間違ってやっていることを知っているか、代替のアプローチを提案できますか?

おかげ

+0

あなたが私のアプローチを試したかどうかは疑問でした。あまりにも単純すぎたのですか? – MPelletier

答えて

3

レスキュー機能を分析する。

解析関数LEADを使用して、そのパーツの次の行のデータを取得することができます。

SQL> ed 
Wrote file afiedt.buf 

    1 with x as (
    2 select 123 part, timestamp '2011-12-08 00:00:00' ts 
    3  from dual 
    4 union all 
    5 select 123, timestamp '2011-12-08 00:00:05' 
    6  from dual 
    7 union all 
    8 select 123, timestamp '2011-12-08 00:00:06' 
    9  from dual 
10 union all 
11 select 456, timestamp '2011-12-08 00:10:23' 
12  from dual 
13 union all 
14 select 789, timestamp '2011-12-08 00:12:13' 
15  from dual 
16 union all 
17 select 123, timestamp '2011-12-08 00:14:32' 
18  from dual 
19 ) 
20 select part, 
21   ts, 
22   lead(ts) over (partition by part order by ts) next_ts 
23* from x 
SQL>/

     PART TS        NEXT_TS 
---------- ------------------------------- ------------------------------- 
     123 08-DEC-11 12.00.00.000000000 AM 08-DEC-11 12.00.05.000000000 AM 
     123 08-DEC-11 12.00.05.000000000 AM 08-DEC-11 12.00.06.000000000 AM 
     123 08-DEC-11 12.00.06.000000000 AM 08-DEC-11 12.14.32.000000000 AM 
     123 08-DEC-11 12.14.32.000000000 AM 
     456 08-DEC-11 12.10.23.000000000 AM 
     789 08-DEC-11 12.12.13.000000000 AM 

6 rows selected. 

あなたはそれをやった後は、その後、あなたはインライン・ビューを作成することができますし、単に次の日は5分以上、現在の日付より後にあるそれらの行を選択します。

SQL> ed 
Wrote file afiedt.buf 

    1 with x as (
    2 select 123 part, timestamp '2011-12-08 00:00:00' ts 
    3  from dual 
    4 union all 
    5 select 123, timestamp '2011-12-08 00:00:05' 
    6  from dual 
    7 union all 
    8 select 123, timestamp '2011-12-08 00:00:06' 
    9  from dual 
10 union all 
11 select 456, timestamp '2011-12-08 00:10:23' 
12  from dual 
13 union all 
14 select 789, timestamp '2011-12-08 00:12:13' 
15  from dual 
16 union all 
17 select 123, timestamp '2011-12-08 00:14:32' 
18  from dual 
19 ) 
20 select part, 
21   ts 
22 from (
23  select part, 
24    ts, 
25    lead(ts) over (partition by part order by ts) next_ts 
26  from x) 
27 where next_ts is null 
28*  or next_ts > ts + interval '5' minute 
SQL>/

     PART TS 
---------- ------------------------------- 
     123 08-DEC-11 12.00.06.000000000 AM 
     123 08-DEC-11 12.14.32.000000000 AM 
     456 08-DEC-11 12.10.23.000000000 AM 
     789 08-DEC-11 12.12.13.000000000 AM 
+0

うわー、ありがとう!便利なリード機能について知らなかった – AFJ

0

これは検証されていないが、基本的に、トリックは5分(床の)で割った部分と時間によってグループにあります。

select part, min(scan_time) 
from data 
group by part, floor(scan_time/(5/1440)) 
order by scan_time; 
1

AFJ、我々はこのフィールドがFalseに設定されている行を取って、そして、場合を教えすることは、以前の5分で、このパートのpreviusエントリが存在する新しいフィールドを持つ

ましょうsupose私たちは結果を持っています。

select 
    Part, 
    DateTime, 
    coalesce(
    (select distinct 1 
    from data ds 
    where ds.Part = d.Part 
     and ds.DateTime between d.DateTime and d.DateTime - 5/1440 
    ) 
    , 0) as exists_previous 
from data d 

サブクエリをチェック

結果がでなければなりませんINTEVAL彼らは以前の5分で同じパートを持つ行している場合:

Part DateTime exists_previous 
123  12:00:00 0 
123  12:00:05 1 
123  12:00:06 1 
456  12:10:23 0 
789  12:12:13 0 
123  12:14:32 0 

、0と行のみを取得するためのフィルタ:

select Part, DateTime from 
    (select 
     Part, 
     DateTime, 
     coalesce(
     (select distinct 1 
     from data ds 
     where ds.Part = d.Part 
      and ds.DateTime between d.DateTime and d.DateTime - 5/1440 
     ) 
     , 0) as exists_previous 
    from data D 
    ) T where T.exists_previous = 0 

免責事項:テストされていません。

+0

ありがとうdanihp。私はクエリの仕組みを理解していますが、サブクエリを正しく動作させることはできません。 exists_previousカラムに "0"を含むすべてのローを返します。 – AFJ

関連する問題