简体   繁体   English

Doctrine查询语言获取每组最大/最新行数

[英]Doctrine Query Language get Max/Latest Row Per Group

I am trying and failing to translate my relatively simple SQL statement into one that will work within Doctrine. 我正在尝试并且未能将我相对简单的SQL语句转换为可在Doctrine中工作的语句。

This is the SQL statement, which works as required when run against my database: 这是SQL语句,在针对我的数据库运行时根据需要运行:

SELECT a.*
 FROM score a
 INNER JOIN (
  SELECT name, MAX(score) AS highest
  FROM score
  GROUP BY name
 ) b
 ON a.score = b.highest AND a.name = b.name
 GROUP BY name
 ORDER BY b.highest DESC, a.dateCreated DESC

Here's the DQL attempt thus far: 这是迄今为止的DQL尝试:

$kb = $em->createQuery(
    "SELECT a 
    FROM ShmupBundle:Score a
    INNER JOIN a.name ShmupBundle:Score b WITH a.score = b.score AND a.name = b.name GROUP BY b.name
    WHERE a.platform='keyboard'
    GROUP BY a.name
    ORDER BY b.score DESC, a.dateCreated DESC"
);

Which is currently giving this error: 目前正在提供此错误:

[Semantical Error] line 0, col 73 near 'ShmupBundle:Score': Error: Class ShmupBundle\Entity\Score has no association named name

The table itself is pretty simple: id, name, score, platform, dateCreated 表本身非常简单:id,name,score,platform,dateCreated

There are multiple entries with the same name, but different scores. 有多个条目具有相同的名称,但分数不同。 I want to show only the "high score" per name. 我想只显示每个名字的“高分”。 I've been trying on and off for a day or two now, with no luck. 我一直在尝试一两天,没有运气。 Can anyone point me in the right direction? 谁能指出我正确的方向?

The query you are trying to do with doctrine is related to . 您尝试使用doctrine进行的查询与 To use a sub query and then join with main query get things complicated to handle with doctrine. 要使用子查询然后与主查询连接,要使用doctrine来处理复杂的事情。 So below is the rewritten SQL version to get the same results without use of any aggregate functions: 所以下面是重写的SQL版本,以便在不使用任何聚合函数的情况下获得相同的结果:

SELECT 
  a.* 
FROM
  score a 
  LEFT JOIN score b 
    ON a.name = b.name 
    AND a.score < b.score 
WHERE b.score IS NULL 
ORDER BY a.score DESC 

DEMO DEMO

To convert above query equivalent to doctrine or DQL is easy, below is the DQL version of above SQL: 要转换上述查询等效于doctrine或DQL很简单,下面是上面SQL的DQL版本:

SELECT a 
FROM AppBundle\Entity\Score a
    LEFT JOIN AppBundle\Entity\Score b 
    WITH a.name = b.name 
    AND a.score < b.score
WHERE b.score IS NULL
ORDER BY a.score DESC

Or with query builder you can write something like i have tested below with symfony 2.8 using the DEMO Schema 或者使用查询构建器,您可以使用DEMO Schema编写类似于我在下面使用symfony 2.8测试的内容

$DM   = $this->get( 'Doctrine' )->getManager();
$repo = $DM->getRepository( 'AppBundle\Entity\Score' );
$results = $repo->createQueryBuilder( 'a' )
                ->select( 'a' )
                ->leftJoin(
                    'AppBundle\Entity\Score',
                    'b',
                    'WITH',
                    'a.name = b.name AND a.score < b.score'
                )
                ->where( 'b.score IS NULL' )
                ->orderBy( 'a.score','DESC' )
                ->getQuery()
                ->getResult();

Another idea would be create a view using your query in database and in symfony create an entity put the view name in table annotation and just start calling your entity it will give the results returned by your query but this approach is not recommended just a temporary fix. 另一个想法是在数据库中使用您的查询创建一个视图,并在symfony中创建一个实体,将视图名称放在表注释中,然后开始调用您的实体,它将给出查询返回的结果,但这种方法不建议只是临时修复。

Inner Join Statement needs first argument as a table, that is a semantic error in your query. Inner Join语句需要第一个参数作为表,这是查询中的语义错误。

$kb = $em->createQuery(
"SELECT a 
FROM ShmupBundle:Score a
INNER JOIN ShmupBundle:Score b ON a.score = b.score AND a.name = b.name GROUP BY b.name
WHERE a.platform='keyboard'
GROUP BY a.name
ORDER BY b.score DESC, a.dateCreated DESC");

use this in class 在课堂上使用它

 $name = $em->getRepository('AppBundle:BlogPost')->getMaxId();

in repository you can use something like 在存储库中,您可以使用类似的东西

 public function getMaxId()
{
$qb = $this->createQueryBuilder('u');
$qb->select('u, MAX(id) as idMax');  
return $qb->getQuery()->getSingleResult();
}
  • MySQL does not understand the : syntax. MySQL不理解:语法。 If ShmupBundle:Score is supposed to be a database and table, then use . 如果ShmupBundle:Score应该是数据库和表,那么使用. . If Doctrine is supposed to replace it with something, then what does it do with it? 如果Doctrine应该用某些东西代替它,那么它用它做什么呢?
  • There can be only one GROUP BY clause, and it must be after the WHERE clause. 只能有一个GROUP BY子句,它必须 WHERE子句之后。 Try removing the GROUP BY b.name . 尝试删除GROUP BY b.name
  • There is no need to GROUP BY both b.name and a.name since they are equal. 因为它们是相同的,所以不需要GROUP BYb.namea.name

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM