从原始查询(带有子查询)到学说查询生成器
From Raw query (with subqueries) To doctrine 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();
}
我想得到的是来自特定学生(校友)的每个主题(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();
我得到:
[Syntax Error] line 0, col 47: Error: Expected Literal, got 'SELECT'
我做错了什么? DQL 查询看起来不错...谢谢
终于查询变得更容易了,我可以做到:
$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();
我必须实体 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();
我得到:
[Syntax Error] line 0, col 47: Error: Expected Literal, got 'SELECT'
我做错了什么? DQL 查询看起来不错...谢谢
终于查询变得更容易了,我可以做到:
$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();