2015-03-02 13 views
5

Tôi đang làm việc với dự án nhỏ sử dụng Symfony 2.5 và Doctrine. Truy vấn của tôi chạy trong MySQL Workbench một cách hoàn hảo. Đáng tiếc là trong học thuyết tôi nhận được báo lỗi dưới đây khi tôi sử dụng dấu ngoặc đơn trong xây dựng truy vấn của tôi:Sử dụng dấu ngoặc đơn (>) trong Symfony 2.5 và trình tạo truy vấn Doctrine

  • QueryException: [Cú pháp Lỗi] dòng 0, col 19: Lỗi: Dự kiến ​​Học thuyết \ ORM \ Query \ lexer :: T_CLOSE_PARENTHESIS, có '>'

    $grades = $qb 
           ->select(array(
            'SUM(g.final > 89.5) as a',        
            'CONCAT (gcs.number, gcs.letter) as class' 
           )) 
           ->from('FicusEschoolBundle:Grade', 'g') 
           ->leftJoin('g.course', 'gc') 
           ->leftJoin('gc.schoolclass', 'gcs') 
           ->where($qb->expr()->eq('gc.subject', $rid)) 
           ->andWhere($qb->expr()->in('g.quarter', $filterQuarter)) 
           ->groupBy('gc') 
           ->orderBy('gcs.number') 
           ->getQuery() 
           ->getArrayResult(); 
    

Trả lời

1

By Học thuyết mặc định không cho phép có điều kiện logic bên trong chức năng tổng hợp. Bạn có thể sử dụng beberlei/DoctrineExtensions hoặc nếu bạn không muốn cài đặt toàn bộ thư viện chỉ cần thêm IF điều kiện duy nhất: https://github.com/beberlei/DoctrineExtensions/blob/master/lib/DoctrineExtensions/Query/Mysql/IfElse.php.

Để đăng ký chức năng tùy chỉnh DQL:

# app/config/config.yml 
doctrine: 
    orm: 
     # ... 
     dql: 
      string_functions: 
       test_string: AppBundle\DQL\StringFunction 
       second_string: AppBundle\DQL\SecondStringFunction 
      numeric_functions: 
       test_numeric: AppBundle\DQL\NumericFunction 
      datetime_functions: 
       test_datetime: AppBundle\DQL\DatetimeFunction 

Nguồn: http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html

1

Bạn không thể chỉ định một điều kiện trong tổng chọn nhà điều hành Doctrine2 DQL, BTW bạn có thể lọc duy nhất có số tiền lớn hơn giới hạn của bạn. Hãy thử điều này:

$grades = $qb 
       ->select(array(
        'SUM(g.final) as a',        
        'CONCAT (gcs.number, gcs.letter) as class' 
       )) 
       ->from('FicusEschoolBundle:Grade', 'g') 
       ->leftJoin('g.course', 'gc') 
       ->leftJoin('gc.schoolclass', 'gcs') 
       ->where($qb->expr()->eq('gc.subject', $rid)) 
       ->andWhere($qb->expr()->in('g.quarter', $filterQuarter)) 
       ->having(
        $qb->expr()->gt(
           $qb->expr()->sum('g.final'), 89.5 
            ) 
       ) 
       ->groupBy('gc') 
       ->orderBy('gcs.number') 
       ->getQuery() 
       ->getArrayResult(); 

Hope trợ giúp này

+0

Bạn truy vấn sẽ tạo ra kết quả sai vì 'SUM (g.final> 89,5) 'là không tương đương với' SUM (g.final)> 89.5' –

+0

Có, tôi biết, tôi đã mô tả truy vấn này là giải pháp thay thế, Cảm ơn bạn đã làm rõ – Matteo

0

Cảm ơn các bạn. Cuối cùng có vẻ như tôi đã tự giải quyết. Ngoài ra tôi không chắc chắn nó là chính xác. Bây giờ nó cho thấy câu trả lời đúng.

Original truy vấn MySQL mà hoạt động hoàn hảo:

SELECT avg(final) as Final, SUM(Final>89.5) as a, SUM(Final<89.5 AND Final>79.5) as b, SUM(Final<79.5 AND Final>69.5) as c, SUM(Final<69.5 AND Final>59.5) as d , SUM(Final<59.5) as f, Ca.letter, Ca.number, subject_id FROM grades as G join courses as C on G.course_id = C.id join schoolclasses as Ca on Ca.id=C.schoolclass_id where C.subject_id = 1 and G.quarter_id in (1, 2) group by G.course_id 

Tôi đã thử nó chuyển sang DQL. Thật không may do các dấu ngoặc đơn của bạn không thể sử dụng trong hàm tổng hợp của Doctrine. Đây là cách tôi giải quyết. Bây giờ nó đếm tất cả A, B, C, D, F từ bảng điểm. Và thông tin về lớp học (thư và số) đã được lấy ra từ bảng cha của nó. Các lớp A, B, C, D, F không phải là trường chính xác mà tôi muốn. Nó giống như hình dưới đây. enter image description here

Nó có thể được loại lừa

$rsm = new ResultSetMapping(); 
      $rsm->addEntityResult('Ficus\EschoolBundle\Entity\Grade', 'g'); 
      $rsm->addFieldResult('g', 'Final', 'final'); 
      $rsm->addFieldResult('g', 'A', 'a'); 
      $rsm->addFieldResult('g', 'B', 'b'); 
      $rsm->addFieldResult('g', 'C', 'c'); 
      $rsm->addFieldResult('g', 'D', 'd'); 
      $rsm->addFieldResult('g', 'F', 'abcd'); 
      $rsm->addFieldResult('g', 'Class', 'a1'); 
      //$query = $this->getEntityManager()->createNativeQuery('SELECT avg(final) as Final, SUM(Final>89.5) as a, SUM(Final<89.5 AND Final>79.5) as b, SUM(Final<79.5 AND Final>69.5) as c, SUM(Final<69.5 AND Final>59.5) as d , SUM(Final<59.5) as f, Ca.letter, Ca.number, subject_id FROM grades as G join courses as C on G.course_id = C.id join schoolclasses as Ca on Ca.id=C.schoolclass_id where C.subject_id = 1 and G.quarter_id=1 group by G.course_id', $rsm); 
      $query = $this->getEntityManager()->createNativeQuery('' 
        . 'SELECT avg(g.final) as Final, ' 
        . 'SUM(Final>89.5) as A, ' 
        . 'SUM(Final<89.5 AND Final>79.5) as B, ' 
        . 'SUM(Final<79.5 AND Final>69.5) as C, ' 
        . 'SUM(Final<69.5 AND Final>59.5) as D, ' 
        . 'SUM(Final<59.5) as F, ' 
        . 'CONCAT(ca.number, ca.letter) as Class ' 
        . 'FROM grades as g ' 
        . 'JOIN courses as c on g.course_id = c.id ' 
        . 'JOIN schoolclasses as ca on ca.id = c.schoolclass_id ' 
        . 'WHERE c.subject_id = ? AND g.quarter_id in (?) group by g.course_id ' 
        . 'ORDER BY ca.number, ca.letter ', $rsm); 
      $query->setParameter(1, $rid); 
      $query->setParameter(2, $filterQuarter); 

      $grades = $query->getArrayResult(); 
Các vấn đề liên quan