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

发布于 2024-11-30 19:59:06 字数 1166 浏览 1 评论 0原文

类似于此处的问题,我试图获取给定项目集的最新结果。因此,如果一台机器有其所在位置的历史记录,我会尝试找到最新的位置:

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询问。因为我不知道如何执行具有多个条件的联接,我求助于 Criteria 的 addJoin()。不幸的是,它没有做我想做的事,而且我不知道如何正确使用它。到目前为止,我已经写了:

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

我不知道如何指定用于每个标准的比较。我也不知道如何使用别名以便我可以成功地将实体与其自身连接起来。我该怎么做?

Similar to the question here, I am attempting to get the latest result for a given set of items. So, if a machine has a history of where it's been, I am trying to find the latest place:

machine:
  id: ~

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

I have adapted the SQL from the linked question like this:

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;

This does as expected, but I would like to transform this into a Propel 1.5 Query. As I do not know how to perform joins with multiple criteria, I am resorting to Criteria's addJoin(). Unfortunately, it's not doing what I would like, and I don't know how to use it properly. So far I have written this:

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

I don't know how to specify the comparison to use for each of the criteria. Nor do I know how to use an alias so that I can successfully join the entity with itself. How might I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月棠 2024-12-07 19:59:06

经过一番研究,Propel 的 ModelCriteria API 不支持任意连接,正如 Propel 用户组 此处。 ModelCriteria 仅适用于模式定义关系的情况,并且由于上例中的表未显式引用自身,因此如果不使用旧的 Criteria 就无法完成此操作。

然而,Propel 1.6 确实支持连接的多个条件,如文档中所述< /a>,如果这对任何人有用的话。但是,您必须确保您拥有 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 对象,但没有找到,Propel 似乎会窒息。

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

After some research, Propel's ModelCriteria API doesn't support arbitrary joins, as explained in the Propel Users group here. ModelCriteria only works where the schema defines relationships, and as the table in the above example doesn't reference itself explicitly, it can't be done without using old Criterias.

Propel 1.6 does, however, support multiple conditions on a join, as described in the documentation, if that's useful for anyone. You would have to make sure you have Propel 1.6, however.

Instead, I had to revert back to a sub-query, which Propel 1.6 also now supports with addSelectQuery. I modified the SQL to look like this:

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

This could then be written using Propel:

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

Be careful when reading the documentation; it's addSelectQuery(), not useSelectQuery().

To accommodate and use within a Query call and allow for joins, I had to convert the items to an array containing their primary keys, and return a search for those primary keys. Propel seemed to choke if I returned the above Query object, sans find.

return $this
  ->filterByPrimaryKeys($latestLocations->toKeyValue('MachineId', 'Id'));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文