Php Symfony2 QueryBuilder按ID顺序返回产品查询

Php Symfony2 QueryBuilder按ID顺序返回产品查询,php,mysql,symfony,query-builder,Php,Mysql,Symfony,Query Builder,我有一个按任意顺序排列的ID列表: array(57, 12, 29, 25, 11) 使用Symfony的QueryBuilder,我只需要从所有数据库对象返回这些产品,它们应该按照特定的顺序返回 我需要返回查询,而不是结果 我正在尝试各种不同的方法: public function querySortedProductsInCategories($id, $type, $slug, $sort) { $qb = $this->createQueryB

我有一个按任意顺序排列的ID列表:

array(57, 12, 29, 25, 11)
使用Symfony的QueryBuilder,我只需要从所有数据库对象返回这些产品,它们应该按照特定的顺序返回

我需要返回查询,而不是结果

我正在尝试各种不同的方法:

    public function querySortedProductsInCategories($id, $type, $slug, $sort)
    {

        $qb = $this->createQueryBuilder('p');
        $qb->addSelect(array('p', 'gallery'));
        $qb->addSelect(array('p', 'media'));
        $qb->addSelect(array('p', 'image'));
        $qb->leftJoin("p." . $type, "c");
        $qb->leftJoin('p.gallery', 'gallery');
        $qb->leftJoin('gallery.galleryHasMedias', 'media');
        $qb->leftJoin('media.media', 'image');
        $qb->where("c." . $type. "= :id ");
        $qb->andWhere("p.status = 1 ");
        $qb->SetParameter('id', $id);
//        $qb->andWhere($qb->expr()->in('p.id', $sort));
//        $qb->andWhere("p.id IN (:sort) ");
//        $qb->SetParameter('sort', $sort);
        return $qb->getQuery();
    }
我在语句中尝试了
。。。。它返回我需要的列表,但顺序不正确

现在我开始认为,这甚至是不可能做到的。Stackoverflow是我发现这一点的最后机会

更新:

试图创建DQL函数,但出现错误。第一次这样做,我不知道发生了什么

class Field extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
{

    /**
     * @override
     */
    public function parse(\Doctrine\ORM\Query\Parser $parser) {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
        $this->stringPrimary = $parser->StringPrimary();
        $parser->match(Lexer::T_COMMA);
        $this->stringSecondary = $parser->StringPrimary();
        $parser->match(Lexer::T_COMMA);
        $this->stringThird = $parser->StringPrimary();
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }


    /**
     * @param \Doctrine\ORM\Query\SqlWalker $sqlWalker
     *
     * @return string
     */
    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        // TODO: Implement getSql() method.
    }

}
查询:

        $em = $this->getEntityManager();
        $doctrineConfig = $em->getConfiguration();
        $doctrineConfig->addCustomStringFunction('FIELD', 'Mp\ShopBundle\Doctrine\Field');

        $qb = $this->createQueryBuilder('p');
        $qb->addSelect(array('p', 'gallery'));
        $qb->addSelect(array('p', 'media'));
        $qb->addSelect(array('p', 'image'));
        $qb->addSelect(array("p, field(p.id, " . implode(", ", $sort) . ") as HIDDEN field"));
        $qb->leftJoin("p." . $type, "c");
        $qb->leftJoin('p.gallery', 'gallery');
        $qb->leftJoin('gallery.galleryHasMedias', 'media');
        $qb->leftJoin('media.media', 'image');
//        $qb->where("p.id = :sort ");
        $qb->where("c." . $type. "= :id ");
        $qb->andWhere($qb->expr()->in('p.id', $sort));
        $qb->andWhere("p.status = 1 ");
        $qb->setParameter('id', $id);
//        $qb->setParameter('sort', $sort);
        $qb->orderBy('field');
        return $qb->getQuery();
错误:

Error: Expected StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression, got '23'
查询:

[1/2] QueryException: SELECT p, p, gallery, p, media, p, image, p, field(p.id, 23, 40, 30, 24, 42, 37, 38, 58, 33, 8, 34, 35, 36, 28, 51, 14, 1) as HIDDEN field FROM Mp\ShopBundle\Entity\Product p LEFT JOIN p.subcategory c LEFT JOIN p.gallery gallery LEFT JOIN gallery.galleryHasMedias media LEFT JOIN media.media image WHERE c.subcategory= :id AND p.id IN(23, 40, 30, 24, 42, 37, 38, 58, 33, 8, 34, 35, 36, 28, 51, 14, 1) AND p.status = 1 ORDER BY field ASC

您可以根据具体情况下订单:

$customOrderString = $this->generateCase($ids);
if(!empty($customOrderString)) {
    $db->addSelect("(CASE {$customOrderString} ELSE 3 END) AS HIDDEN ORD ");
    $db->orderBy('ORD', 'DESC');
}
return $qb->getQuery();

 .....
private generateCase($ids) {
    $caseString = '';
    foreach($ids as $index=>$id) {
        $caseString .= "WHEN $id THEN $index";
    }
    return $caseString;
}

您可以根据具体情况下订单:

$customOrderString = $this->generateCase($ids);
if(!empty($customOrderString)) {
    $db->addSelect("(CASE {$customOrderString} ELSE 3 END) AS HIDDEN ORD ");
    $db->orderBy('ORD', 'DESC');
}
return $qb->getQuery();

 .....
private generateCase($ids) {
    $caseString = '';
    foreach($ids as $index=>$id) {
        $caseString .= "WHEN $id THEN $index";
    }
    return $caseString;
}

使用MySQL,您可以创建一个DQL函数,以便能够使用:

见其他类似问题:


使用MySQL,您可以创建一个DQL函数,以便能够使用:

见其他类似问题:



调用此方法时,返回值是多少?我得到了产品列表,但它们只是从第一个到最后一个顺序排列的。调用此方法时,返回值是多少?我得到了产品列表,但它们只是从第一个到最后一个顺序排列的。当然。。。但那不是我需要的。orderBy只能订购asc或desc。。我需要按我的数组(57、12、29、25、11)排序注释部分://$qb->andWhere(“p.id IN(:sort)”);//$qb->SetParameter('sort',$sort)$排序是数组10分钟,我会发布答案,尽管你可以根据这些键而不是sortwell键创建一个关联数组,当然它可以。。。但那不是我需要的。orderBy只能订购asc或desc。。我需要按我的数组(57、12、29、25、11)排序注释部分://$qb->andWhere(“p.id IN(:sort)”);//$qb->SetParameter('sort',$sort)$sort是数组10分钟后我将发布答案虽然您可以基于这些键而不是SortHanks创建关联数组,但看起来我需要在symfony中安装DoctrineExtension捆绑包。。你知道女巫是对的吗?不是。您必须编写自己的DQL“FIELD”函数。Docs和这个bundle已经实现了这个功能(以及更多功能):但它已经很旧了。我不知道,它是否仍然适用于最新版本的学说。这里有一件看起来很有趣的事情:我建议简单地复制一下贝伯雷的解决方案。如果您不知道如何安装整个库,只需学习
Field
课程即可。谢谢,看起来我需要在symfony中安装DoctrineExtension包。。你知道女巫是对的吗?不是。您必须编写自己的DQL“FIELD”函数。Docs和这个bundle已经实现了这个功能(以及更多功能):但它已经很旧了。我不知道,它是否仍然适用于最新版本的学说。这里有一件看起来很有趣的事情:我建议简单地复制一下贝伯雷的解决方案。如果您不知道如何安装整个库,只需学习
Field
课程即可。