我正在使用 PHP Doctrine ORM 来构建我的查询。但是,我似乎不太清楚如何使用 DQL(Doctrine Query Language)编写以下 WHERE 子句:

WHERE name='ABC' AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X') 
AND price > 10

如何指定括号的位置?

我目前的 PHP 代码是这样的:

->where('name = ?', 'ABC')
->andWhere('category1 = ?', 'X')
->orWhere('category2 = ?', 'X')
->orWhere('category3 = ?', 'X')
->andWhere('price > ?', 10)

但这会产生类似的东西

WHERE name='ABC' AND category1 = 'X' OR category2 = 'X' OR category3 = 'X' 
AND price > 10

由于操作顺序,它不会返回预期结果。

另外,“where”、“andWhere”和“addWhere”方法之间有区别吗?

更新好吧,看来你不能使用 DQL 进行复杂的查询,所以我一直在尝试手动编写 SQL 并使用 andWhere() 方法来添加它。然而,我正在使用 WHERE..IN 和 Doctrine 似乎去掉了我的括号:

$q->andWhere("(category1 IN $subcategory_in_clause
            OR category2 IN $subcategory_in_clause 
            OR category3 IN $subcategory_in_clause)");
有帮助吗?

解决方案

从我的经验,每个复数where功能括号(我使用学说1.2.1)内进行分组。

$q->where('name = ?', 'ABC')
  ->andWhere('category1 = ? OR category2 = ? OR category3 = ?', array('X', 'X', 'X'))
  ->andWhere('price < ?', 10)

产生以下SQL:

WHERE name = 'ABC' 
  AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X')
  AND price < 10

其他提示

正确的方法可以在以下位置找到: 学说 2 - 查询生成器条件查询...如果陈述? 正如@Jekis 所指出的。以下是如何使用表达式生成器来解决这个问题,就像@anushr 的示例一样。

$qb->where($qb->expr()->eq('name', ':name'))
  ->andWhere(
    $qb->expr()->orX(
      $qb->expr()->eq('category1', ':category1'),
      $qb->expr()->eq('category2', ':category2'),
      $qb->expr()->eq('category3', ':category3')
  )
  ->andWhere($qb->expr()->lt('price', ':price')
  ->setParameter('name', 'ABC')
  ->setParameter('category1', 'X')
  ->setParameter('category2', 'X')
  ->setParameter('category3', 'X')
  ->setParameter('price', 10);

,因为它似乎就像你不能使用DQL做复杂的查询,我写了下面的SQL传递给andWhere()方法:

$q->andWhere("(category1 IN $subcategory_in_clause
OR category2 IN $subcategory_in_clause 
OR category3 IN $subcategory_in_clause) AND TRUE");

请注意在“AND TRUE”,一劈,使得分析器不忽略外括号中。

andWhere可以概括为:
以前加入的条件(s)认识到其中声明

你可以安全使用 andWhere 就地的 哪里.(它引入了一个非常微小的开销,这是下文所述,在第2列的项目。)

执行andWhere是:(学说1.2.3)

public function andWhere($where, $params = array())
{
    if (is_array($params)) {
        $this->_params['where'] = array_merge($this->_params['where'], $params);
    } else {
        $this->_params['where'][] = $params;
    }

    if ($this->_hasDqlQueryPart('where')) {
        $this->_addDqlQueryPart('where', 'AND', true);
    }

    return $this->_addDqlQueryPart('where', $where, true);
}

这可以读作

  1. 过程参数
  2. 追加 声明 哪里 一部分的查询, 如果另一个在哪里发言的加入之前
  3. 附加条件

至于之间,其中,andwhere,和addwhere,我不相信存在来自我最后一次读出的源的显著差异的差异。我建议你阅读学说源,但是。这真的很简单,并有助于在文档中的孔填充(有很多)。至于复杂,语句,我这个不知道自己,但还没有一个需要它。

在我的经验,我有时可见之间的差:

$q->andWhere("(category1 IN $subcategory_in_clause
            OR category2 IN $subcategory_in_clause 
            OR category3 IN $subcategory_in_clause)");

$q->andWhere("(category1 IN $subcategory_in_clause OR category2 IN $subcategory_in_clause OR category3 IN $subcategory_in_clause)");

的第一个语句是写在3条线,第二,上唯一的一个。我不相信它,但是是有区别的!

$q->andWhere("category1 IN ( $subcategory_in_clause )
              OR category2 IN ( $subcategory_in_clause )
              OR category3 IN ( $subcategory_in_clause )");

你会这么好心来试试这个变型,不知道它的工作原理,但值得一试。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top