从原始查询(带有子查询)到学说查询构建器

时间:2019-10-06 15:14:59

标签: php doctrine-orm doctrine symfony4 query-builder

我必须进入实体Nota(标记)和Asignatura(主题):

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

    /**
     * @ORM\Column(type="integer")
     */
    private $n_convocatoria;

    /**
     * @ORM\Column(type="date")
     */
    private $fecha;

    /**
     * @ORM\Column(type="float")
     */
    private $nota;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Alumno", inversedBy="notas")
     * @ORM\JoinColumn(nullable=false)
     */
    private $alumno;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Asignatura", inversedBy="notas")
     * @ORM\JoinColumn(nullable=false)
     */
    private $asignatura;
...

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

    /**
     * @ORM\Column(type="integer", unique=true)
     */
    private $codigo;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $nombre;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $nombre_ingles;

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    private $credects;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Grado", inversedBy="asignaturas")
     * @ORM\JoinColumn(nullable=false)
     */
    private $grado;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Alumno", mappedBy="asignaturas")
     */
    private $alumnos;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Nota", mappedBy="asignatura")
     */
    private $notas;

    public function __construct()
    {
        $this->alumnos = new ArrayCollection();
        $this->notas = new ArrayCollection();
    }

我要获取的是来自特定学生(alumno)的每个主题(Asignatura)的最后记录。我有一个Raw查询,但是我需要使用查询生成器创建它,因为我需要实体Nota和Asignatura。

原始查询是:

SELECT 
    *
FROM
    (SELECT 
        id, nota, alumno_id, fecha, asignatura_id, n_convocatoria
    FROM
        nota n
    WHERE
        fecha IN (SELECT 
                MAX(fecha)
            FROM
                nota
            GROUP BY asignatura_id
            HAVING id = n.id)
    AND alumno_id = 1) AS temp
    JOIN
    asignatura a ON temp.asignatura_id = a.id
    ;

我想要实现的是:

$qb  = $this->_em->createQueryBuilder('temp');
        $subFechas = $qb;
        $subFechas->select('MAX(s.fecha) ')
            ->from('App\Entity\Nota', 's')
            ->groupBy('s.asignatura')
            ->having('n.id=s.id')
            ->andHaving('s.alumno = ?val')
            ->setParameter('val', $id);
        //dd($subFechas->getDQL()); //"SELECT MAX(fecha) as temp FROM nota s GROUP BY asignatura HAVING id=s.id AND alumno = :val"
        $qb2  = $this->_em->createQueryBuilder();

        $qb2->select('n.id, n.nota, n.alumno, n.fecha, n.asignatura, n.n_convocatoria')
            ->from('App\Entity\Nota' , 'n')
            ->join('App\Entity\Asignatura','a')
            ->where($qb->expr()->in('n.fecha',$subFechas->getDQL()));

        $qb3 = $this->_em->createQueryBuilder('nota3');
        $qb3->select('note, a')
            ->from('App\Entity\Nota' , 'note')
            ->where($qb2->getDQL());
        dd($qb3->getDQL());

//"SELECT note, a FROM App\Entity\Nota note WHERE SELECT n.id, n.nota, n.alumno, n.fecha, n.asignatura, n.n_convocatoria FROM App\Entity\Nota n INNER JOIN App\Entity\Asignatura a WHERE n.fecha IN(SELECT MAX(s.fecha)  FROM App\Entity\Nota s GROUP BY s.asignatura HAVING n.id=s.id AND s.alumno = ?val) "

但是当我执行时:

$qb3->getQuery()->getSQL();

我得到:

  

[语法错误]第0行,第47行:错误:预期字面量为'SELECT'

我做错了什么? DQL查询看起来不错...谢谢

1 个答案:

答案 0 :(得分:0)

最终查询要容易一些,我可以实现:

$sub = $this->createQueryBuilder('n');

        $sub->select('MAX(n.fecha)')
            ->where('n.alumno = :id')
            ->groupBy('n.asignatura');

        $qb  = $this->_em->createQueryBuilder('main');
        $qb->select('mm')
            ->from('App:Nota', 'mm')
            ->where($qb->expr()->In('mm.fecha', $sub->getDQL())
            );

        $qb->setParameter('id', $id);
        $query  = $qb->getQuery();

        return $query->getResult();
相关问题