使用Propel 1.5查找套装中的最新内容

时间:2011-08-19 14:15:09

标签: php mysql symfony1 symfony-1.4 propel

与问题here类似,我试图获取给定项目集的最新结果。所以,如果一台机器有历史记录,我正试图找到最新的地方:

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 Query。由于我不知道如何perform joins with multiple criteria,我正在使用Criteria的addJoin()。不幸的是,它不是我想做的,我不知道如何正确使用它。到目前为止,我写了这个:

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

我不知道如何指定要用于每个条件的比较。我也不知道如何使用别名,以便我可以成功地加入实体。我怎么能这样做?

1 个答案:

答案 0 :(得分:0)

经过一些研究,Propel的ModelCriteria API不支持任意连接,如Propel Users组here中所述。 ModelCriteria仅适用于模式定义关系的地方,并且由于上例中的表未明确引用自身,因此不使用旧的Criterias就无法完成。

Propel 1.6确实支持加入的多个条件,如documentation中所述,如果这对任何人都有用。但是,您必须确保拥有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调用中容纳和使用并允许连接,我必须将项目转换为包含其主键的数组,并返回搜索这些主键。如果我返回上面的Query对象,Propel似乎会窒息,无法找到。

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