我正在尝试使用Doctrine进行子查询的查询。现在它给了我一个错误。我在存储库中的功能是:
public function getRecentPlaylists($count = 3) {
$q = $this->_em->createQuery("
SELECT p.id,
p.featuredImage,
p.title,
p.slug,
a.firstName,
a.lastName,
a.slug as authorSlug,
(SELECT updated
FROM \Entities\Articles
ORDER BY updated DESC LIMIT 1) as updated
FROM \Entities\Playlist p
JOIN \Entities\Account a
ON p.account_id = a.id
")
->setMaxResults($count);
try{
return $q->getResult();
}catch(Exception $e){
echo $e->message();
}
}
这给了我这个错误:
[Semantical Error] line 0, col 210 near 'LIMIT 1) as updated FROM': Error: Class 'LIMIT' is not defined.
我几乎放弃了Doctrine,我无法弄清楚如何使用带有子查询的子查询或联合进行查询。有什么帮助这个功能?谢谢!
答案 0 :(得分:5)
您可以非常轻松地将自己的语法添加到Doctrine中,例如将LIMIT 1
添加到子查询中,如Colin O'Dell explained on his blog。
// AppBundle\DBAL\FirstFunction
<?php
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\AST\Subselect;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
/**
* FirstFunction ::=
* "FIRST" "(" Subselect ")"
*/
class FirstFunction extends FunctionNode
{
/**
* @var Subselect
*/
private $subselect;
/**
* {@inheritdoc}
*/
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->subselect = $parser->Subselect();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
/**
* {@inheritdoc}
*/
public function getSql(SqlWalker $sqlWalker)
{
return '(' . $this->subselect->dispatch($sqlWalker) . ' LIMIT 1)';
}
}
# app/config/config.yml
doctrine:
# ...
orm:
# ...
dql:
string_functions:
FIRST: AppBundle\DBAL\FirstFunction
使用如下:
$dqb->from('MyAppBundle:Foo', 'foo')
->leftJoin('foo.bar', 'bar', 'WITH', 'bar = FIRST(SELECT b FROM MyAppBundle:Bar b WHERE b.foo = foo AND b.published_date >= :now ORDER BY t.startDate)');
答案 1 :(得分:3)
在这种情况下,您可以使用Doctrine的聚合表达式MAX来获取最新日期:
SELECT MAX(a.updated) FROM AppBundle:Article a
您不需要使用LIMIT。
答案 2 :(得分:-5)
你需要的是取出内部查询并为其单独创建DQL,然后使用生成的DQL
$inner_q = $this->_em
->createQuery("SELECT AR.updated FROM \Entities\Articles AR ORDER BY AR.updated DESC")
->setMaxResults(1)
->getDQL();
$q = $this->_em->createQuery("SELECT p.id,
p.featuredImage,
p.title,
p.slug,
a.firstName,
a.lastName,
a.slug as authorSlug,
(".$inner_q.") AS updated
FROM \Entities\Playlist p
JOIN \Entities\Account a
ON p.account_id = a.id
")
->setMaxResults($count);
try{
return $q->getResult();
}
catch(Exception $e){
echo $e->message();
}