Reputation: 4561
I need to create a QueryBuilder with union, is that possible ?
$qb = $this->em->createQueryBuilder()
->select('table1.numObject AS id')
->select ('table1.name AS name')
->from("MyBundle:Table1", "table1")
and union
->select('table2.id AS id')
->select ('table2.name AS name')
->from("MyBundle:Table2", "table2")
Note : it has to be a queryBuilder object (not query or something else)
Thank you
Upvotes: 5
Views: 11532
Reputation: 1556
As Tomaz answered above, it's not possible to create a UNION
using the createQueryBuilder
function but we can achieve it by using createNativeQuery
. Please check the below example,
public function firstQuery(array $filters) {
$qb = $this->em->createQueryBuilder()
->select('table1.numObject AS id, table1.name AS name')
->from("MyBundle:Table1", "table1");
return $qb->getQuery();
}
public function secondQuery(array $filters) {
$qb = $this->em->createQueryBuilder()
->select('table2.numObject AS id, table2.name AS name')
->from("MyBundle:Table2", "table2");
return $qb->getQuery();
}
// Main function
public function getAPIResult(array $filters, int $pageSize, int $page) {
$rsm = new ResultSetMappingBuilder($this->em);
$rsm->addScalarResult('id', 'id', 'integer');
$rsm->addScalarResult('id', 'name', 'string');
$sql = "SELECT * FROM (
({$this->firstQuery($filters)->getSQL()})
UNION ALL
({$this->secondQuery($filters)->getSQL()})
) tmp
ORDER BY name
LIMIT ? OFFSET ?
";
$query = $this->em->createNativeQuery($sql, $rsm);
$this->em->setParameter(1, $pageSize)
->setParameter(2, $pageSize * ($page-1));
return $query->getScalarResult();
}
Check official docs for Scalar Result: https://www.doctrine-project.org/projects/doctrine-orm/en/2.15/reference/native-sql.html#scalar-results
Note: The above code snippet is not tested, please put a comment if face any issues.
Hope it helps. Happy coding ;)
Upvotes: 1
Reputation: 4803
It's not possible via the Doctrine
syntax, but it is possible using plain SQL and a statement:
$conn = $this->getEntityManager()->getConnection();
$sql = <<<SQL
SELECT numObject AS id, name FROM table1
UNION // or UNION ALL if you want duplicates
SELECT id, name FROM table2
SQL;
try {
$stmt = $conn->prepare($sql);
$stmt->execute();
return $stmt->fetchAll();
} catch (DBALException $e) {
return [];
}
This will give you either an array with the rows you requested or an empty array in case of an error.
Upvotes: 1
Reputation: 10900
Unfortunately UNION
is not possible within Doctrine
. You have to fetch two sets from database and do "union" manually on php side or use native sql.
Check this issue for more information
Upvotes: 8