Найти последние в наборе с Propel 1.5 - PullRequest
0 голосов
/ 19 августа 2011

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

machine:
  id: ~

machine_history:
  machine_id:
    type: integer
    foreignTable: machine
  location_id:
    type: integer
    foreignTable: location
  time:
    type: timestamp
    required: true

Я адаптировал SQL из связанного вопроса следующим образом:

SELECT l1.* FROM machine_history l1
LEFT JOIN machine_history l2 ON
  (l1.machine_id = l2.machine_id AND l1.time < l2.time)
WHERE l2.id IS NULL;

Это соответствует ожиданиям, но я хотел бы преобразовать это в запрос Propel 1.5.Поскольку я не знаю, как выполнять соединения по нескольким критериям , я прибегаю к критерию addJoin().К сожалению, он не делает то, что хотел бы, и я не знаю, как правильно его использовать.До сих пор я написал это:

return $this
  ->addJoin(
    array(MachineLocationPeer::ID, MachineLocationPeer::TIME),
    array(MachineLocationPeer::ID, MachineLocationPeer::TIME),
    Criteria::LEFT_JOIN
  )
  ->filterById(null);

Я не знаю, как указать сравнение для использования для каждого из критериев.Также я не знаю, как использовать псевдоним, чтобы я мог успешно присоединиться к сущности.Как я могу это сделать?

1 Ответ

0 голосов
/ 14 сентября 2011

После некоторых исследований API Propel ModelCriteria не поддерживает произвольные объединения, как описано в группе пользователей Propel здесь . ModelCriteria работает только тогда, когда схема определяет отношения, и, поскольку таблица в приведенном выше примере не ссылается сама на себя, это невозможно сделать без использования старых критериев.

Propel 1.6, однако, поддерживает несколько условий для объединения, как описано в документации , если это полезно для кого-либо. Вы должны убедиться, что у вас есть Propel 1.6 , однако.

Вместо этого мне пришлось вернуться к подзапросу, который Propel 1.6 теперь также поддерживает с addSelectQuery. Я изменил SQL, чтобы он выглядел так:

SELECT * FROM (
  SELECT * FROM machine_location
  ORDER BY time DESC
) AS times GROUP BY times.machine_id;

Это можно написать с помощью Propel:

$times = MachineLocationQuery::create()
  ->orderByTime('desc');
$latestLocations = MachineLocationQuery::create()
  ->addSelectQuery($times, 'times')
  ->groupBy('MachineId')
  ->find();

Будьте внимательны при чтении документации; это addSelectQuery(), а не useSelectQuery().

Чтобы разместить и использовать в вызове Query и разрешить объединения, мне пришлось преобразовать элементы в массив, содержащий их первичные ключи, и вернуть поиск этих первичных ключей. Пропел, казалось, задохнулся, если я вернул вышеупомянутый объект запроса, без поиска.

return $this
  ->filterByPrimaryKeys($latestLocations->toKeyValue('MachineId', 'Id'));
...