1

プロジェクトで、ステータスが変更される請求書を管理しています。ステータスの変更は、次のような別のデータベース テーブルに保存されます。

|id|invoice_id|user_id|old_status_id|new_status_id|change_date        |
-----------------------------------------------------------------------
| 1|         1|      1|            1|            3|2013-11-11 12:00:00|
| 2|         1|      2|            3|            5|2013-11-11 12:30:00|
| 3|         2|      3|            1|            2|2013-11-10 08:00:00|
| 4|         1|      1|            5|            6|2013-11-11 13:10:00|
| 5|         2|      2|            2|            5|2013-11-10 09:00:00|

請求書ごとに、最後のステータス変更を取得したいと考えています。したがって、結果には ID 4 と 5 のレコードが含まれているはずです。

|id|invoice_id|user_id|old_status_id|new_status_id|change_date        |
-----------------------------------------------------------------------
| 4|         1|      1|            5|            6|2013-11-11 13:10:00|
| 5|         2|      2|            2|            5|2013-11-10 09:00:00|

Invoice_id でグループ化して max(change_date) を使用すると、最も若い日付が取得されますが、他のフィールドのフィールド値は、グループ内で最も若い日付を含むレコードから取得されません。

それが私にとっての課題 1 です。

課題 2 は、可能であれば、CakePHP のメソッドを使用してクエリを実現することです。

課題 3 は、現在のユーザーに属するレコードに結果をフィルター処理することです。SO 現在のユーザーの ID が 1 の場合、結果は次のようになります。

|id|invoice_id|user_id|old_status_id|new_status_id|change_date        |
-----------------------------------------------------------------------
| 4|         1|      1|            5|            6|2013-11-11 13:10:00|

ユーザー ID が 2 の場合、結果は次のようになります。

|id|invoice_id|user_id|old_status_id|new_status_id|change_date        |
-----------------------------------------------------------------------
| 5|         2|      2|            2|            5|2013-11-10 09:00:00|

ID 3 のユーザーの場合、結果は空になります。

つまり、ユーザーが最後に変更を行ったかどうかに関係なく、ユーザーが行った最新の変更をすべて検索する必要はありません。代わりに、そのユーザーがこれまでに変更を加えたすべての請求書の変更を見つけたいと考えています。動機は、ユーザーが自分の変更を元に戻せるようにしたいということです。これは、別の変更を行った後に他のユーザーがいない場合にのみ可能です。

4

1 に答える 1

0

誰かが答えを必要とする場合

以下に厳密に焦点を当てています。

そのユーザーが最後に変更を加えたすべての請求書の変更を検索したい

SQL を次のように記述します。

SELECT foo.*
FROM foo
LEFT JOIN foo AS after_foo
  ON foo.invoice_id = after_foo.invoice_id
    AND foo.change_date < after_foo.change_date
WHERE after_foo.id IS NULL
  AND foo.user_id = 1;

JOINCakephp の 内の句を使用して実装しfindます。


提案されたアルゴリズムの SQL は次のようなものです。

SELECT foo.*
FROM foo
JOIN (SELECT invoice_id, MAX(change_date) AS most_recent
      FROM foo
      GROUP BY invoice_id) AS recently
  ON recently.invoice_id = foo.invoice_id
    AND recently.most_recent = foo.change_date
WHERE foo.user_id = 1;
于 2014-12-23T12:42:23.200 に答える