Subquery's with limit in Doctrine/Symfony using DQL - symfony

I would like to know how can I set limit on 1 query and then query based on the selected results.
For example I want to select the last 100 posts and the do some operation.
$first_query= $this->getEntityManager()
->createQuery(
'SELECT p FROM TestBundle:Post p ORDER BY p.date DESC'
)
->setMaxResults(5);
How to use this result to select from it in the next query?
return $this->getEntityManager()
->createQuery(
"SELECT u.username , max(p.date),d.points,l.name
FROM $first_query
JOIN p.location l JOIN p.user u JOIN u.deeds d
WHERE l.name = :location
GROUP BY u.id
ORDER BY d.points DESC , p.date DESC
"
)
->setParameter('location' , $location)
->getResult();

I found out that DQL doesn't support limits so I went for native sql.
$stmt = $this->getEntityManager()->getConnection()->prepare($query);
$stmt->execute();
return $stmt->fetchAll();
This way you can do whatever you want with the $query varaible you can set limits and everythign as it's a normal sql statement.

Related

Doing a subquery inside a where with Doctrine 2 querybuilder

I am trying (without success) to translate this SQL query inside a Doctrine2 querybuilder. How should I do to include the subselect inside a Where with Querybuilder ?
SQL query I am trying to implement with querybuilder :
SELECT * FROM `message` A
WHERE A.id =
(SELECT B.id FROM `message` B
WHERE (A.user_id = B.user_id AND A.receiver_id = B.receiver_id) OR (A.user_id = B.receiver_id AND A.receiver_id = B.user_id)
ORDER BY creationdate DESC
LIMIT 1)
So far, I tried something like this in Message repository but I guess I am far away from the good way to do it :
public function getConversations()
{
$qb = $this
->createQueryBuilder('A')
->Where('A.id IN
(SELECT B.id FROM Message B
WHERE (A.user_id = B.user_id AND A.receiver_id = B.receiver_id) OR (A.user_id = B.receiver_id AND A.receiver_id = B.user_id)
ORDER BY creationdate DESC
LIMIT 1')
;
return $qb
->getQuery()
->getResult()
;
}
}
This trigger error message:
Error: Class 'Message' is not defined.
For people interested I finally found a solution. I did the query like this (if someone has another solution I am very interested):
public function getConversations()
{
$rawSql = "SELECT * FROM `message` A
WHERE A.id =
(SELECT B.id FROM `message` B
WHERE (A.user_id = B.user_id AND A.receiver_id = B.receiver_id) OR (A.user_id = B.receiver_id AND A.receiver_id = B.user_id)
ORDER BY creationdate DESC
LIMIT 1)
";
$stmt = $this->getEntityManager()->getConnection()->prepare($rawSql);
$stmt->execute([]);
return $stmt->fetchAll();
}

DqlBuilder don't return values but mysql do

I have method findByTag() which should return entites with %#i% but it won't. This is sql which dql builded:
SELECT p0_.id AS id_0, p0_.content AS content_1, p0_.date AS date_2, p0_.user_id AS user_id_3 FROM post p0_ INNER JOIN user u1_ ON p0_.user_id = u1_.id LEFT JOIN points p2_ ON p0_.id = p2_.post_id LEFT JOIN comments c3_ ON p0_.id = c3_.post_id WHERE p0_.content LIKE '%#i%' ORDER BY p0_.date DESC LIMIT 20 if i enter it to mysql it return it ok.
Anybody have an idea?
$dql = $this->createQueryBuilder('p')
->innerJoin('p.user', 'c')
->leftJoin('p.points', 'pp')
->leftJoin('p.comments', 'cc')
->Where('p.content LIKE \'%#i%\'')
->setMaxResults($max)
->orderBy('p.date','DESC');
$dql->getQuery()
->getResult();
return $dql;
try it
$dql = $this->createQueryBuilder()
->from('YourBundleName:YourEntityName', 'p')
->innerJoin('YourBundleName.user', 'c')
->leftJoin('YourBundleName.points', 'pp')
->leftJoin('YourBundleName.comments', 'cc')
->Where('p.content LIKE \'%#i%\'')
->setMaxResults($max)
->orderBy('p.date','DESC');
return $dql->getQuery()->getResult();

DQL access id from object property with left join

I realized this sql which works without problems
SELECT meeting.name, meeting.date, community.name, participation.isPresent, participation.user_id
FROM meeting
INNER JOIN community
ON meeting.community_id = community.id
AND community.is_active = 1
LEFT join participation
ON meeting.id = participation.meeting_id
AND participation.user_id = 1078
WHERE meeting.date >= CURRENT_DATE()
ORDER BY meeting.date DESC
I'm trying to reproduce it with the doctrine query builder but I never got the right result. The user id part doesn't seem to be part of the leftJoin function but is applied to the request globally, which is not what I want.
public function getNextMeetings()
{
$qb = $this->createQueryBuilder('m')
->select('m.name AS meeting, m.date, c.name AS community, p.isPresent', 'IDENTITY(p.user) AS user')
->innerJoin('m.community', 'c')
->where('c.isActive = true')
->leftJoin('m.participations', 'p')
//->leftJoin('p.user', 'u')
//->where('u.id = 1078 OR u.id IS NULL')
//->where('IDENTITY(p.user) = 1078')
->andWhere('m.date >= CURRENT_DATE()')
->orderBy('m.date', 'DESC');
return $qb->getQuery()->execute();
}
My comments are what I tried to fix this issue.
Check Working with QueryBuilder: High level API methods
More precisely, the definition od leftJoin() function:
public function leftJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null);
You can place a condition on the joined Entity by:
use Doctrine\ORM\Query\Expr;
->leftJoin('m.participations', 'p', Expr\Join::WITH, 'p.user = :userId')
->setParameter('userId', 1078)
Note you do not need a condition for "meeting.id = participation.meeting_id", as this is autoapplied by the relation m.participations to the join constructed.

Doctrine left join where joined table is null shows results

the goal of this query is to show records from table orders that don't have any shipments created yet. Here is how it should be done in SQL:
SELECT *
FROM orders
LEFT JOIN orders_shipments shipments ON orders.trx_id = shipments.trx_id
WHERE shipments.shipment_id IS NULL
AND orders.purchase_date IS NOT NULL
AND orders.fulfillment_channel = 'MFN';
The following query shows 0 results. Vs the following:
$qb = $this->createQueryBuilder('orders');
$qb->select('orders, shipments')
->leftjoin('orders.shipments', 'shipments')
->Where('shipments.id IS NULL')
->ANDWhere('orders.purchaseDate IS NOT NULL')
->ANDWhere('orders.fulfillmentChannel = :a')->setParameter('a', 'MFN');;
$results = $qb->getQuery()
->getResult();
return $results;
Does show results. Why is that and how to fix it?
Not sure why but I had to use GROUP and HAVING to get it to work:
$qb = $this->createQueryBuilder('orders');
$qb->select('orders, shipments')
->leftjoin('orders.shipments', 'shipments')
->Where('shipments.id IS NULL')
->ANDWhere('orders.purchaseDate IS NOT NULL')
->ANDWhere('orders.fulfillmentChannel = :a')->setParameter('a', 'MFN')
->GroupBy('orders.id')
->having('count(shipments) = 0');
$results = $qb->getQuery()->getResult();

Symfony DQL syntax error

I'm trying to do DQL query, but having some troubles with it...
$user = $this->getUser();
$query = $em->createQuery(
'SELECT p
FROM AppBundle:User u
JOIN AppBundle:Follower f
JOIN AppBundle:Photo p
WHERE u.id = :id
AND f.follower_id = :id
AND p.user_id = f.user_id'
)->setParameter('id', $user->getId());
I am trying to get Photos (AppBundle:Photo) of those users, to whom the logged user is following.
Getting next error:
`[Syntax Error] line 0, col 128: Error: Expected =, <, <=, <>, >, >=, !=, got 'p'`
Whats wrong here with 'p' ?
I don't understand why follower are in your code, I don't see relation with photo...
After, I think you call Join but I don't see the relation you made with the photo...
$query = $em->createQuery(
'SELECT p
FROM AppBundle:Photo p
JOIN p.user u
WHERE u.id = :id ')->setParameter('id', $user->getId());
Here is a part of the official doc :
Example:
Regular join of the address:
createQuery("SELECT u FROM User u JOIN u.address a
WHERE a.city = 'Berlin'"); $users = $query->getResult();
Fetch join of the address:
createQuery("SELECT u, a FROM User u JOIN
u.address a WHERE a.city = 'Berlin'"); $users = $query->getResult();
did yu try this?:
$query = $em->createQuery(
'SELECT p
FROM AppBundle:Photo p
JOIN AppBundle:Follower f
JOIN AppBundle:User u
WHERE u.id = :id
AND f.follower_id = :id
AND p.user_id = f.user_id' )->setParameter('id', $user->getId());

Resources