От необработанного запроса (с подзапросами) до построителя запроса доктрины - PullRequest
1 голос
/ 06 октября 2019

У меня есть сущности 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();
    }

Я пытаюсь получить Последнее примечание по каждому предмету (Asignatura) от конкретного ученика (выпускника). У меня работает необработанный запрос, но мне нужно создать его с помощью построителя запросов, потому что мне нужны сущности 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 Query выглядит хорошо ... спасибо

1 Ответ

0 голосов
/ 07 октября 2019

Наконец, запрос стал немного проще, и я смог добиться этого:

$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();
...