2011-12-21 1 views
0

タイトルが十分説明できない場合は、ご容赦ください。ここ
は私の問題のシナリオです:前のレコードに対して条件付きでデータを計算するクエリ

私は、次の列(アップ製)を持つテーブルがある:

oid rev state time 
1  0 S T1 
2  0 S T2 
1  0 A T3 
2  0 A T4 
2  1 MS T5 
2  1 MA T6 
2  1 M T7 
2  2 MS T8 
2  2 M T9 

時間列がvarchar型(日付/時刻を含む)
である私が見つける必要があります。 - 状態から状態へ遷移する各注文にかかる時間は、有効な状態遷移は次のように定義されています

S->A 
MS->MA 
MS-M 

(すなわち、移行は、ACKに提出する修正から得ることができます-submit to modify-ackまたはmodify-submitted to modified) とMSからMAとMへの移行が可能ですが、この場合はMSからMAへの移行にのみ関心があります。上記で

oid 1 transitioned from S to A. 
oid 2 changed from S to A (rev 0) 
oid 2 changed from MS to MA (rev 1) - here we don't want to consider transition to M 
oid 2 changed from MS to M (rev 2) 

(timeTakenはmillisecsであろう)以下のようにクエリ出力は次のようになります

oid rev timeTaken state 
1 0 (T3-T1) A 
2 0 (T4-T2) A 
2 1 (T6-T5) MA 
2 2 (T9-T8) M 

したがって、現在のレコードの状態は、MAまたはMの時間差である場合前回のレコード状態がMSの場合にのみ計算する必要があります(これは、oid、rev、timeで指定されているものとします)。現在のレコード状態がMの場合は、前のレコード状態がMAの場合はスキップします。

これは、mysqlのsqlクエリを使用して実行する必要がありますか。任意のポインタが役立ちます。ありがとう。

====
テーブルにはプライマリキーとして時刻があります。

私は(それがどのような方法で助けている場合)、それは正しい方法で注文を取得するには、このクエリを持って

OID、REVを選択し、状態、オーダーから時間受注コード、時間によっては、その意志

を吹け与える:

OID REV状態時間
1 0 S T1
1 0 A T3
2 0 S T2
2 0 A T4
を2 1 MS T5
2 1 MA T6
2 1 M T7
2 2 MS T8
2 2 M T9

この役立つだろうか?

+0

質問、元のテーブルに何らかの自動インクリメントIDがある場合、これははるかに簡単です。それは? –

+0

と時刻がソートされていると仮定できますか? –

+0

私は正しい方法で注文するためにこのクエリを持っています: –

答えて

0

ええと、これはあなたがデータベースではなくコードで行うべきことだと思います。

私はSQLでこれを行う方法を考えることができますが、それはちょっと複雑です。 このようになります。元のテーブルがt1であるとします。

  1. 各oid、rev内のすべての可能な遷移を含むビューを作成します。

    create view transitions as 
        select a.oid, a.rev, a.state as state_from, b.state as state_to, 
          a.time as time_from, b.time as time_to 
        from t1 as a, t1 as b 
        where a.oid=b.oid 
         and a.rev=b.rev 
         and a.time<b.time; 
    
    
    +------+------+------------+----------+-----------+---------+ 
    | oid | rev | state_from | state_to | time_from | time_to | 
    +------+------+------------+----------+-----------+---------+ 
    | 1 | 0 | S   | A  |  T1 |  T3 | 
    | 2 | 0 | S   | A  |  T2 |  T4 | 
    | 2 | 1 | MS   | MA  |  T5 |  T6 | 
    | 2 | 1 | MS   | M  |  T5 |  T7 | 
    | 2 | 1 | MA   | M  |  T6 |  T7 | 
    | 2 | 2 | MS   | M  |  T8 |  T9 | 
    +------+------+------------+----------+-----------+---------+ 
    
  2. 注:この手順は必要ありませんが、教育目的のために!)時間が連続していないすべてを剪定。それは今、あなたはちょうどstate_fromstate_toはあなたが興味のあるものを移行しているところtime_from-time_toを選択したい

    select a.* 
    from transitions as a 
    join (
        select oid, rev, time_from, min(time_to) as time_to 
        from transitions 
        group by time_from 
        ) as b 
        on a.oid=b.oid and a.rev=b.rev 
        and a.time_from=b.time_from and a.time_to=b.time_to; 
    
    +------+------+------------+----------+-----------+---------+ 
    | oid | rev | state_from | state_to | time_from | time_to | 
    +------+------+------------+----------+-----------+---------+ 
    | 1 | 0 | S   | A  |  T1 |  T3 | 
    | 2 | 0 | S   | A  |  T2 |  T4 | 
    | 2 | 1 | MS   | MA  |  T5 |  T6 | 
    | 2 | 1 | MA   | M  |  T6 |  T7 | 
    | 2 | 2 | MS   | M  |  T8 |  T9 | 
    +------+------+------------+----------+-----------+---------+ 
    
  3. (そうではなくT5->T7T5->T6かかります)各time_fromの最小time_toで行を取ることによってこれを行います。そのステップ2は必要ありませんので、あなたが前のクエリでこれを組み合わせることができます(ステップ2からの唯一の新しいものがあり、最後および/または/またはビット):

    select a.oid,a.rev,a.state_to as state,a.time_to-a.time_from as timeTaken 
    from transitions as a 
    join (
        select oid, rev, time_from, min(time_to) as time_to 
        from transitions 
        group by time_from 
        ) as b 
        on a.oid=b.oid and a.rev=b.rev 
        and a.time_from=b.time_from and a.time_to=b.time_to 
    and ( (a.state_from='S' and a.state_to='A') 
        or (a.state_from='MS' and a.state_to='MA') 
        or (a.state_from='MS' and a.state_to='M') 
        ); 
    
    +------+------+-------+-----------+ 
    | oid | rev | state | timeTaken | 
    +------+------+-------+-----------+ 
    | 1 | 0 | A  | T3-T1 | 
    | 2 | 0 | A  | T4-T2 | 
    | 2 | 2 | M  | T6-T5 | 
    | 2 | 1 | MA | T9-T8 | 
    +------+------+-------+-----------+ 
    

要約すると、ステップ1)を実行してビューを作成し、計算を実行するたびにステップ3)を実行します。

もっと効率的なやり方があると思います。それは本当に私の特権ではありません。 joinを実行することは、すべてwhere節に移動するよりも安く、ビューを作成することはちょっとした費用です。

+0

これは本当に役立ちます!ありがとう! –

関連する問題