【问题标题】:Doctrine EXSIT and NOT EXIST存在与不存在的教义
【发布时间】:2020-06-04 16:17:13
【问题描述】:

我有查询,我需要转换为学说查询生成器,但我遇到了错误,如何正确执行?

我的查询

SELECT id FROM category
WHERE 
  EXISTS(SELECT 1 FROM category_relations WHERE main_category_id = category.id)
  AND
  NOT EXISTS(SELECT 1 FROM category_relations WHERE sub_category_id = category.id)

如我所料

    $subYes = $this->getEntityManager()->createQueryBuilder();
    $subYes->select("1");
    $subYes->from(CategoryRelations::class,"cr_y");
    $subYes->andWhere('cr_y.mainCategory = c');

    $subNot = $this->getEntityManager()->createQueryBuilder();
    $subNot->select("1");
    $subNot->from(CategoryRelations::class,"cr_n");
    $subNot->andWhere('cr_n.subCategory = c');

    $qb = $this->createQueryBuilder('c');
    $qb
        ->select('c')
        ->where($qb->expr()->exists($subYes->getDQL()))
        ->andWhere($qb->expr()->not($subNot->getDQL()));


    $query = $qb->getQuery();
    $DQL = $query->getDQL();
    $SQL = $query->getSQL();
    $result = $query->getResult();

和错误

[Syntax Error] line 0, col 140: Error: Expected Literal, got 'SELECT'

更新

SELECT c FROM App\Entity\Category c 
WHERE EXISTS(SELECT 1 
FROM App\Entity\CategoryRelations cr_y WHERE cr_y.mainCategory = c) 
AND NOT(SELECT 1 FROM App\Entity\CategoryRelations cr_n WHERE cr_n.subCategory = c)

更新

我内部加入 mainCategory 和 subCategory 但仍然面临错误

$subYes = $this->getEntityManager()->createQueryBuilder();
$subYes
    ->select("cr_y")
    ->from(CategoryRelations::class,"cr_y")
    ->innerJoin('cr_y.mainCategory', 'cr_ym')
    ->where($subYes->expr()->eq('cr_ym.id', 'c.id'));

$subNot = $this->getEntityManager()->createQueryBuilder();
$subNot
    ->select("cr_n")
    ->from(CategoryRelations::class,"cr_n")
    ->innerJoin('cr_y.subCategory', 'cr_nm')
    ->where($subNot->expr()->eq('cr_nm.id', 'c.id'));

$qb = $this->createQueryBuilder('c');
$qb
    ->select('c')
    ->where($qb->expr()->exists($subYes->getDQL()))
    ->andWhere($qb->expr()->not($subNot->getDQL()));


$query = $qb->getQuery();
$DQL = $query->getDQL();
$SQL = $query->getSQL();
$result = $query->getResult();

这是我的实体

class Category

/**
 * @ORM\OneToMany(targetEntity="CategoryRelations", mappedBy="subCategory")
 * @ORM\Cache("NONSTRICT_READ_WRITE")
 */
private $subCategoryRelations;

/**
 * @ORM\OneToMany(targetEntity="CategoryRelations", mappedBy="mainCategory")
 * @Annotation\Groups({Category::SERIALIZED_GROUP_RELATIONS_LIST})
 * @ORM\Cache("NONSTRICT_READ_WRITE")
 */
private $mainCategoryRelations;

还有多对多CategoryRelations

class CategoryRelations
{
    use TimestampableEntity;

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="subCategoryRelations", cascade={"persist"})
     * @Annotation\Groups({Category::SERIALIZED_GROUP_RELATIONS_LIST})
     * @ORM\Cache("NONSTRICT_READ_WRITE")
     */
    private $subCategory;

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="mainCategoryRelations", cascade={"persist"})
     * @ORM\Cache("NONSTRICT_READ_WRITE")
     */
    private $mainCategory;

【问题讨论】:

  • 您是否回显了 DQL 和 SQL?
  • DQL 是的,当我遇到错误的 SQL 时,我更新了我的问题
  • 您的 dql 查询有一部分基本上读作“WHERE ... AND NOT(子查询)”,这在语义上没有意义,而不是子查询,您必须有一些可以评估为标量的东西- 因此出现错误“预期文字,得到选择”。您的查询生成器代码也反映了问题。

标签: php symfony doctrine


【解决方案1】:

您可以使用查询生成器中的“not()/in()”方法来添加您想要的过滤器/约束,您的子句看起来像

$subYes = $this->createQueryBuilder("cr")
                         ->select("cr.mainCategory")
                         ->from("CategoryRelations","cr")
                         ->getDQL();

$subNot = $this->createQueryBuilder("cr")
                          ->select("cr.subCategory")
                          ->from("CategoryRelations","cr")
                          ->getDQL();

$qb = $this->createQueryBuilder("c");
 $qb->select("c")
    ->from("Category", "c");
    ->where(
        $qb->expr()->not(
            $qb->expr()->in(
            "c.id",
            $subNot
            )
        )
    )
    ->andWhere(
        $qb->expr()->in(
        "c.id",
        $subYes
        )   
    );
$query = $qb->getQuery();
$DQL = $query->getDQL();
$SQL = $query->getSQL();
$result = $query->getResult();

Reference: Doctrine Query Builder nested orX and andX conditions with join

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 2010-09-15
    • 1970-01-01
    • 2015-09-22
    相关资源
    最近更新 更多