使用status_history
表来保存entries
中特定记录的状态被修改的日期和时间,我正在尝试找到获取当前状态的最简单方法,AKA ,最新日期的状态。
例如,请考虑以下事项:status_history
+----+----------+------------+-----------+
| id | entry_id | status | timestamp |
+----+----------+------------+-----------+
| 1 | 1 | Processing | 15:05:09 |
| 2 | 1 | In Review | 15:05:18 |
| 3 | 1 | Complete | 15:05:26 |
+----+----------+------------+-----------+
当然,我们的条目是:entries
+----+--------+
| id | title |
+----+--------+
| 1 | Foobar |
+----+--------+
如何使用DQL 检索特定条目的最新状态(技术上是当前状态),而无需维护latest_status_id
列在我的Entry
实体中?
考虑调用$entry->getCurrentStatus()
将返回"Complete"
。但是,如果我们有该条目的大量状态记录,则加载所有状态的第二个查询可能会变为性能下降。
注意:在this article中,他们使用额外的列方法来描述它,使用锁定机制进行并发。我想避免这种方法,除非这是正确的方法,因为我们试图不为每个表(status_history.entry_id
和entry.latest_history_id
)建立双重关系。
答案 0 :(得分:1)
对于单个条目,查询可能如下所示:
$query = $em->createQuery('SELECT e, s
FROM entries e
JOIN e.status_history s
WHERE e.entry_id = :entry_id
ORDER BY s.timestamp DESC');
$query->setParameter('entry_id', $entry_id);
$entries = $query->getSingleResult();
在getCurrentStatus()
方法中,您可以返回唯一分配的status_history对象。
对于所有条目,它更复杂,您必须使用带有GROUP BY
和MAX()
的子查询。它在本机SQL中是可行的,但我还没有弄清楚如何使用DQL。一旦我找到解决方案,我会立即更新我的答案。
答案 1 :(得分:0)
我认为在状态历史存储库中使用QueryBuilder
就足够了:
$entry_id = 1;
$queryBuilder = $this->createQueryBuilder()
->select('s')
->where('s.entry = :entry_id')
->orderBy('o.id', 'DESC')
->setParameter('entry_id', $entry_id)
$query = $queryBuilder->getQuery();
return $query->getSingleResult();
您可以使用id,假设id是“自动增量”,timestamp
是创建记录的自动时间戳。在这种情况下,最高ID始终是最新的插入,因此您甚至不需要使用timestamp
列来查找该记录。
否则,您必须在timestamp
列中添加索引,然后按该列排序:
$entry_id = 1;
$queryBuilder = $this->createQueryBuilder()
->select('s')
->where('s.entry = :entry_id')
->orderBy('o.timestamp', 'DESC')
->setParameter('entry_id', $entry_id)
$query = $queryBuilder->getQuery();
return $query->getSingleResult();
您需要在timestamp
列中添加索引以提高性能