是否可以按主键的一部分对 DQL 查询进行分组并返回具有 max() 日期时间记录(早于参考日期)的记录?
Posted
技术标签:
【中文标题】是否可以按主键的一部分对 DQL 查询进行分组并返回具有 max() 日期时间记录(早于参考日期)的记录?【英文标题】:Is it possible to group a DQL query by a portion of the primary key and return records with max() datetime record (earlier than a reference date)? 【发布时间】:2016-09-27 12:13:25 【问题描述】:在一个原则查询中,我怎样才能group by
只在复合主键中的一些变量?在下面的情况下,Category
和 Product
(但不是 Iterator
)?
示例
下表应保留价格随时间变化的历史记录 (Transactions
)。我正在尝试编写一个学说查询以返回最新的日期记录(在参考日期之前):
Category (PK) | Product (PK) | Iterator (PK) | CreateDT | Amount
1 1 1 2016-01-01 100
1 1 2 2016-04-01 150
1 2 1 2016-09-01 50
2 1 1 2016-01-01 75
2 1 2 2016-01-31 80
2 1 3 2016-09-01 90
使用上述作为参考,我试图得到的结果是每个类别/产品一条记录如下:
一)。考虑Category=1
并与参考日期2016-02-01
进行比较:
Category (PK) | Product (PK) | Iterator (PK) | CreateDT | Amount
1 1 1 2016-01-01 100
1 2 1 2016-09-01 50
b)。仅与参考日期2016-02-01
进行比较:
Category (PK) | Product (PK) | Iterator (PK) | CreateDT | Amount
1 1 1 2016-01-01 100
1 2 1 2016-09-01 50
2 1 2 2016-01-31 80
代码
我的尝试是下面的,但它不起作用(在理想的世界中,我希望 `$category 是可选的):
public function findActiveIterationByDate($category, $refdate)
return $this->getEntityManager()
->createQuery(
'SELECT b3
FROM AppBundle:Transaction t1
INNER JOIN
(SELECT t2
FROM AppBundle:Transaction t2, max(createDT) as createDT
WHERE t2.Category=$category, t2.createDT <= $refdate
GROUP BY t2.Category, t2.Product) as t3
ON t1.Category=t3.Category AND t1.Product=t3.Product'
)
->getResult();
错误
但是,尝试这样做会给我以下错误 - 我不确定问题是我的 INNER JOIN 还是 DQL 无法按部分主键分组?
[Doctrine\ORM\Query\QueryException] [语义错误] 第 0 行,第 102 列靠近 '(SELECT t2 ':错误:未定义类 '('。
【问题讨论】:
【参考方案1】:错误是因为您不能在JOIN
语句中使用子查询。您可以在DQL syntax declartation 中看到它。更具体地说是 Join
和 JoinAssociationDeclaration
定义。
我认为您可以将INNER JOIN
语句移动到SELECT
子查询中,并尽可能使WHERE
条件更具限制性,即使这可能会降低性能。
也许更好的是写一个Native SQL 并将结果映射到相对简单且有据可查的 Doctrine 实体。见http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/native-sql.html#the-resultsetmapping。
【讨论】:
感谢@Martin 的回答——我尝试使用复合键的唯一原因是为了最大限度地提高性能。但是,如果它可能降低性能,那么这不是我想要的 - 我将把它们取出并用任意id
主键替换它们......!
如果性能很重要,那么使用 Native SQL,你可以做任何你想做的事情,只需将结果映射到 Doctrine 实体。以上是关于是否可以按主键的一部分对 DQL 查询进行分组并返回具有 max() 日期时间记录(早于参考日期)的记录?的主要内容,如果未能解决你的问题,请参考以下文章