教义:如何使用查询生成器进行嵌套查询?

问题描述

晚上好

SQL查询和学说查询生成器中,我仍然是初级。 我的问题很简单,是如此简单,以至于我已经搜索了几个小时。

我正在使用symfony 4.4 LTS项目。 我有一个表,代表在电子商务网站上下的订单。有4个字段:id,custommer_id,created_at,状态

我想要什么:

状态为“新”且ID后代为ID的最近20条过去的订单

如果我进行SQL查询


SELECT *
FROM order o
WHERE o.status = 'new'.
ORDER BY o.created_at DESC,o.id DESC
limit 20

这是失败的,因为我没有按降序获得ID。我仍然很难理解为什么。

最后我在sql中找到了这个解决方案:

   SELECT * 
        FROM 
        (
            SELECT * 
            FROM order o 
            WHERE o.status = 'new'. 
            ORDER by created_at DESC 
            LIMIT 20 
        ) table_order
        ORDER by id DESC

很酷!我通过降序获得ID的最后20条命令。

现在,我必须使用Doctrine的createqueryBuilder来做到这一点。 我尝试了很多解决方案,但均未成功。 你能帮我么? 预先谢谢你

解决方法

假设您的Entity类的名称为Order

$orders = $entityManager
    ->createQueryBuilder()
    ->from(Order::class,'o')
    ->select('o')
    ->where('o.status = :newStatus')
    ->setParameter('newStatus','new')
    ->orderBy('o.created_at','DESC')
    ->addOrderBy('o.id','DESC')    
    ->getQuery()
    ->setMaxResults(20)
    ->getResult();

但是有了DQL,它会更好:

$orders = $entityManager
    ->createQuery('
        SELECT o 
        FROM App\Entity\Order o
        WHERE o.status = :newStatus
        ORDER BY 
            o.created_at DESC AND
            o.id DESC
    ')
    ->setParameters(['newStatus' => 'new'])
    ->setMaxResults(20)
    ->getResult();
,

通过dateid获取最后20个订单几乎是相同的...

顺序越晚,id越大。

如果在10:32:17下的订单的ID为59
然后在此之后下的订单,可以在10:32:29说,
将会得到ID 60

除非您收到太多订单以至于它们在同一秒内发生,
eitheir的dateid排序是相同的。

只需通过id对其进行订购:

public function getLastNewOrders() {
    $qb=$this->_em->createQueryBuilder();

    $qb->select("order")
       ->from(Order::class,"order")
       ->andWhere($qb->expr()->eq("order.status","new")
       ->orderBy("order.id","DESC")
       ->setMaxResults(20);

    return $qb->getQuery()->getResult();
}
,

非常感谢您的明确回答。 我的帖子不够精确。 相对而言,这是对我的第一份工作进行的技术测试。

我收到了一个带有夹具的symfo项目。 运行灯具时,“订单”表中的数据非常不一致。也就是说,您在建议按ID或created_At进行排序时建议的Preciel逻辑无法保留。 让我解释一下:

查看“订单”表中的最后9条命令。看一下ID,它们的顺序非常不一致。 这样做显然是为了使测试更加复杂吗?我不知道。

table order

如果我以status ='new'减少表格订单的最后5个订单,我会得到:

table order

我被要求按降序对它们进行排序,所以我想得到这个:

table order

因此,您提出的解决方案不会按ID降序排列。

炖牛肉: 您向我提出了这个建议:

$orders = $entityManager
    ->createQueryBuilder()
    ->from(Order::class,'DESC')    
    ->getQuery()
    ->setMaxResults(20)
    ->getResult(); 

我明白了,所以不好。

table order

使用这样的sql请求,很好:

  SELECT * 
        FROM 
        (
            SELECT * 
            FROM order o 
            WHERE o.status = 'new'. 
            ORDER by created_at DESC 
            LIMIT 20 
        ) table_order
        ORDER by id DESC

但是我不能用querybulder做到这一点。

非常感谢您的宝贵时间。