【问题标题】:Subquery with LIMIT in Doctrine [duplicate]Doctrine 中带有 LIMIT 的子查询
【发布时间】:2014-06-05 19:44:55
【问题描述】:

我正在尝试使用 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,我无法弄清楚如何使用子查询或联合子查询进行查询。这个功能有什么帮助吗?谢谢!

【问题讨论】:

  • 我对 Doctrine 没有任何经验,但是您是否尝试过将 as 大写为 AS

标签: php mysql symfony zend-framework doctrine-orm


【解决方案1】:

您可以很容易地将自己的语法添加到 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)');

【讨论】:

  • 但是如果我需要怎么办,例如LIMIT 15?这会有所帮助,教义返回错误,即子查询返回许多结果(而不是一个。
  • 你是我的英雄 @simon-epskamp!非常感谢。我对函数SUB_LIMIT( &lt;limit&gt;, &lt;subquery&gt; )进行了更改
【解决方案2】:

在这种情况下,您可以使用 Doctrine 的聚合表达式 MAX 来获取最近的日期:

SELECT MAX(a.updated) FROM AppBundle:Article a

您不需要使用 LIMIT。

【讨论】:

    【解决方案3】:

    你需要的是取出内部查询并为此单独制作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();
    }
    

    【讨论】:

    • 感谢您的回答。这给了我错误:第 0 行,'a' 附近的 col 289:错误:标识变量 \Entities\Account 用于连接路径表达式,但之前未定义。
    • @raygo 你可以var_dump($q-&gt;getSQL()); 然后将查询粘贴到你的 MySQL 数据库中,看看错误在哪里;玩弄 SQL 查询来修复它,然后在 DQL 中应用这些更改
    • @raygo 此外,您确定内部查询吗?因为它甚至不是你总是选择第一条记录的连接
    • 是的,我要播放列表的日期,我想要属于该播放列表的最后一篇文章的日期
    • 这不起作用 setMaxResults 在子查询中被忽略
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    相关资源
    最近更新 更多