문제

PHP 교리 ORM을 사용하여 쿼리를 구축하고 있습니다. 그러나 DQL (Doctrine Query Language)을 사용하여 다음 위치를 작성하는 방법을 알아낼 수는 없습니다.

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", Where "및"Addwhere "방법 사이에 차이가 있습니까?

업데이트좋아, DQL을 사용하여 복잡한 쿼리를 수행 할 수없는 것 같아서 SQL을 수동으로 작성하고 () 메소드를 사용하여 추가하려고했습니다. 그러나 나는 어디를 사용하고있다.

$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을 썼습니다.

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

파서가 외부 괄호를 무시하지 않도록 "and true"를 주목하십시오.

그리고 여기서는 다음과 같이 요약 할 수 있습니다.
이전에 추가 된 조건 (들)은 어디에서 진술을 인식합니다

안전하게 사용할 수 있습니다 그리고 어디서나 대신에 어디. (매우 작은 오버 헤드가 소개되는데, 이는 두 번째 목록 항목에 아래에 언급되어 있습니다.)

그리고 어디서 구현은 다음과 같습니다. (교리 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. 조건을 추가하십시오

어디에서, 어디서나 추가하는 곳의 차이에 관해서는, 나는 마지막으로 소스를 읽을 때와 큰 차이가 있다고 생각하지 않습니다. 그러나 나는 당신이 교리 출처를 읽도록 권장합니다. 정말 간단하고 문서의 구멍을 채우는 데 도움이됩니다 (많은 것이 있습니다). 복잡한 곳의 진술에 관해서는, 나는 이것을 직접 궁금해했지만 아직 필요하지 않았습니다.

내 경험상, 나는 때때로 다음 사이의 차이를 보았습니다.

$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