(под)запрос CakePHP для получения самой молодой записи каждой группы

В проекте я управляю счетами, статус которых меняется на протяжении всего срока их действия. Изменения статуса сохраняются в другой таблице базы данных, которая похожа на эту:

|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|

Для каждого счета я хотел бы получить последнее изменение статуса. Таким образом, результат должен содержать записи с идентификаторами 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 — отфильтровать результат по тем записям, которые принадлежат текущему пользователю. ТАК, если текущий пользователь имеет идентификатор 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|

Если он или она имеет идентификатор пользователя 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|

Для пользователя с идентификатором 3 результат будет пустым.

Другими словами, я не хочу найти все последние изменения, внесенные пользователем, независимо от того, внес ли он изменения последним. Вместо этого я хочу найти все изменения в счете-фактуре, где этот пользователь был последним, кто внес изменения. Мотивация заключается в том, что я хочу дать пользователю возможность отменить свое изменение, что возможно только в том случае, если ни один другой пользователь после него не внес другое изменение.


person Christian Kirchhoff    schedule 11.11.2013    source источник


Ответы (1)


Если кому нужен ответ

Строго ориентируясь на:

Я хочу найти все изменения в счетах, где этот пользователь был последним, кто внес изменения

Напишите 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;

Реализуйте с помощью предложения JOIN в файле Cakephp 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;
person AgRizzo    schedule 23.12.2014