2

MySQL (5.5) でちょっと厄介なデータを扱っています。ステータス (新規、アクティブ、非アクティブなど) と「場所」の変更の両方を追跡するために使用されるテーブルがあります。場所は x.0.y の形式で、x と y は正の整数です。

場所の変更を別のテーブルに移動しようとしていますが、そのためにはテーブル内の他のレコードから古い場所を完全に復元する必要があります。以下に示すように、完全な古い場所は場所変更レコードに保存されません。

id      status      new_loc     timestamp
--      ------      -------     ---------
5       1 -> 1      1.0.2       2012-05-21 00:00:00
5       new         1.0.1       2012-05-21 00:00:03
5       1 -> 2      2.0.1       2012-05-22 00:00:00
5       2 -> 3      3.0.1       2012-05-23 00:00:00

そのため、場所の変更が発生した場合、記録されるのは完全な新しい場所と古い場所の最初の部分 (ステータス メッセージの左側) だけです。ただし、以前の記録を参照して、完全な古い場所を見つけることができます。

私の主な問題は、そこの2列目です。「新規」ステータスは、ID 5 のオブジェクトがデータベースに追加されたばかりであることを意味します。これは常に、テーブル内の ID の最初のステータスである必要があります。ただし、最初の変更レコードの約 3 秒後に「新しい」レコードが挿入される場合が多くあります。この場合、ロケーション 1.0.1 で追加され、1.0.2、2.0.1、3.0.1 の順に変更されています。(編集: 実際の例はこれほど単純でも単純でもありませんが、人間がかなり簡単に識別できる場所の「パス」が常に存在します。)

行 1 と行 3 の両方を考慮したクエリを作成しようとすると、問題が発生します。最新のレコードが正しくない可能性があるため、見つけることができません。複数の一致がある可能性があるため、自分のステータスに一致する new_loc でレコードを取得することはできません。

これが私がうまくいくと思うものです:

  1. 存在する場合は、最新の以前の場所の変更を見つけ、その new_loc を使用します。
  2. 以前の変更が存在しない場合は、その ID の「新規」ステータスのレコードを見つけて、その new_loc を使用します。

現在、これらの条件の両方に一致する LEFT JOIN がありますが、「条件 1 に一致するものがない場合は条件 2 でのみ結合する」または「条件 1 で結合された行を優先する」と言う方法がわかりません。

これを行う方法がわかりません。どんな助けでも大歓迎です。

編集: id はオブジェクト ID であり、このテーブルの単なるインデックスではないことを明確にする必要があります。主キーは (id, status) です。

4

1 に答える 1

0

あなたがやろうとしていることを理解していることを確認させてください。疑似コードでは、これはあなたが探していることをしますか?

given
   table A (as in your answer)
   table B (objectid, old, new)
for any `id`
   get all rows
   order rows by `status` column such that 'new' is the first value, and then numerically
   take the location in the first `status` column c and insert it into table B with values id, 'new', (c).location
   for all remaining `status` fields selected: 
       for any field n, insert into table B with values id, (n-1).location, (n).location

これはストアド プロシージャを使用して実行できるはずですが、コードを書くのは少し面倒かもしれません。

于 2012-05-22T21:11:25.317 に答える