小编典典

您可以使用Doctrine 2 DQL加入子查询吗?

sql

有没有办法在联接WITH子句中访问联接实体的关系?我试图避免IN在子查询中使用子句。

编辑: 还是有一种方法可以联接子查询而不是使用IN

即确保连接对象的t.final值为1。

尝试避免此查询

SELECT o
FROM Entity\Order o
WHERE o.status = :orderStatus
AND o.id NOT IN (
  SELECT o2.id
  FROM Entity\ServiceRequest s
  JOIN s.order o2
  JOIN s.serviceType t
  WHERE s.status = :serviceStatus
  AND t.final = 1
)

重写尝试失败: 无法访问s.serviceType.final

SELECT o
FROM Entity\Order o
LEFT JOIN o.serviceRequests s
    WITH s.status = :serviceStatus
    AND s.serviceType.final = 1
LEFT JOIN s.serviceType t
WHERE o.status = :orderStatus
AND COUNT(s) = 0

订单实体:

<?php
namespace Entity;

/**
 * @Entity(repositoryClass="Repository\Order")
 * @Table(name="orders")
 */
class Order
{
  const STATUS_REVIEW    = 0;
  const STATUS_PENDING   = 1;
  const STATUS_SCHEDULED = 2;
  const STATUS_COMPLETE  = 3;

  /**
   * @Id
   * @Column(type="integer")
   * @GeneratedValue
   *
   * @var int
   */
  protected $id;

  /**
   * @ManyToOne(targetEntity="Invoice")
   *
   * @var Invoice
   */
  protected $invoice;

  /**
   * @Column(type="integer")
   *
   * @var int
   */
  protected $status;

  /**
   * @Column(type="smallint", name="is_canceled")
   *
   * @var int
   */
  protected $isCanceled;

  /**
   * @OneToMany(targetEntity="ServiceRequest", mappedBy="order")
   *
   * @var ServiceRequest[]
   */
  protected $serviceRequests;

  /**
   * @return int
   */
  public function getId()
  {
    return $this->id;
  }

  /**
   * @return \Entity\Invoice
   */
  public function getInvoice()
  {
    return $this->invoice;
  }

  /**
   * @return int
   *
   * @uses \Entity\Order::STATUS_REVIEW
   * @uses \Entity\Order::STATUS_PENDING
   * @uses \Entity\Order::STATUS_SCHEDULED
   * @uses \Entity\Order::STATUS_COMPLETE
   */
  public function getStatus()
  {
    return $this->status;
  }

  /**
   * @param int $status
   *
   * @uses \Entity\Order::STATUS_REVIEW
   * @uses \Entity\Order::STATUS_PENDING
   * @uses \Entity\Order::STATUS_SCHEDULED
   * @uses \Entity\Order::STATUS_COMPLETE
   */
  public function setStatus($status)
  {
    $this->status = $status;
  }

  /**
   * @return int
   */
  public function getIsCanceled()
  {
    return $this->isCanceled;
  }

  public function cancel()
  {
    $this->isCanceled = 1;
  }

  /**
   * @return ServiceRequest[]
   */
  public function getServices()
  {
    return $this->services;
  }
}

ServiceRequest实体:

/**
 * @Entity
 * @Table(name="order_service_requests")
 */
class ServiceRequest
{
  const STATUS_REVIEW    = 0;
  const STATUS_PENDING   = 1;
  const STATUS_SCHEDULED = 2;
  const STATUS_COMPLETE  = 3;

  /**
   * @Id
   * @Column(type="integer")
   * @GeneratedValue
   *
   * @var int
   */
  protected $id;

  /**
   * @ManyToOne(targetEntity="Invoice")
   *
   * @var Invoice
   */
  protected $invoice;

  /**
   * @ManyToOne(targetEntity="ServiceType")
   * @JoinColumn(name="service_types_id")
   *
   * @var ServiceType
   */
  protected $serviceType;

  /**
   * @ManyToOne(targetEntity="Order")
   * @JoinColumn(name="orders_id")
   *
   * @var Order
   */
  protected $order;

  /**
   * @Column(type="integer")
   *
   * @var int
   */
  protected $status;

  /**
   * @Column(type="smallint", name="is_canceled")
   *
   * @var int
   */
  protected $isCanceled;

  /**
   * @return int
   */
  public function getId()
  {
    return $this->id;
  }

  /**
   * @return \Entity\Invoice
   */
  public function getInvoice()
  {
    return $this->invoice;
  }

  /**
   * @return int
   *
   * @uses \Entity\ServiceRequest::STATUS_REVIEW
   * @uses \Entity\ServiceRequest::STATUS_PENDING
   * @uses \Entity\ServiceRequest::STATUS_SCHEDULED
   * @uses \Entity\ServiceRequest::STATUS_COMPLETE
   */
  public function getStatus()
  {
    return $this->status;
  }

  /**
   * @param int $status
   *
   * @uses \Entity\ServiceRequest::STATUS_REVIEW
   * @uses \Entity\ServiceRequest::STATUS_PENDING
   * @uses \Entity\ServiceRequest::STATUS_SCHEDULED
   * @uses \Entity\ServiceRequest::STATUS_COMPLETE
   */
  public function setStatus($status)
  {
    $this->status = $status;
  }

  /**
   * @return \Entity\ServiceType
   */
  public function getServiceType()
  {
    return $this->serviceType;
  }

  /**
   * @return int
   */
  public function isCanceled()
  {
    return $this->isCanceled;
  }

  public function getOrder()
  {
    return $this->order;
  }
}

ServiceType实体:

<?php
namespace Entity;

/**
 * @Entity
 * @Table(name="service_types")
 */
class ServiceType
{
  /**
   * @Id
   * @Column(type="integer")
   * @GeneratedValue
   *
   * @var int
   */
  protected $id;

  /**
   * @Column(type="smallint")
   *
   * @var int
   */
  protected $final;

  /**
   * @return int
   */
  public function getId()
  {
    return $this->id;
  }

  /**
   * @return int
   */
  public function getFinal()
  {
    return $this->final;
  }
}

阅读 223

收藏
2021-04-07

共1个答案

小编典典

您要在加入服务类型之前对其进行查询。尝试:

SELECT o
FROM Entity\Order o
LEFT JOIN o.serviceRequests s
  WITH s.status = :serviceStatus
LEFT JOIN s.serviceType t
WHERE o.status = :orderStatus
AND COUNT(s) = 0
AND t.final = 1
2021-04-07