与问题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);
我不知道如何指定要用于每个条件的比较。我也不知道如何使用别名,以便我可以成功地加入实体。我怎么能这样做?
答案 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'));