Doctrine - select last 4 rows from table - symfony

I'm using Symfony/Doctrine.
I'm trying to select last 4 rows from table, but im getting error.
$em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery(
'SELECT c FROM DprocMainBundle:Courses c ORDER BY id DESC LIMIT 4'
);
$course = $query->getResult();
This is my query but it shows error.
Expected end of string, got 'LIMIT'
How should i use limit, and get the LAST 4 rows?
thanks!

Use setMaxResults() to limit the number of results.
$course = $query->setMaxResults(4)->getResult();
If you want to use this for pagination you can add a setFirstResult() call.
$course = $query->setMaxResults(4)->setFirstResult(10)->getResult();

Related

How to add a count number to an array of data : Doctrine

In fact, after returning a result of data from the database using Doctrine,
I'm trying to add the row count number, without calling another query request.
This is my function:
public function search(QueryBuilder $qb, string $search)
{
$qb = $qb->addSelect('COUNT(n) as count');
$search = $this->escape($search);
$qb->andWhere(
$qb->expr()->like('n.title', $qb->expr()->literal('%'.$search.'%'))
);
$qb->setMaxResults(2);
}
This is my DQL:
SELECT n, COUNT(n) as count FROM CoreBundle\Entity\News n LEFT JOIN n.category c WHERE n.title LIKE '%re%'
And I need to return as a result a all my data with a count key that refer to the number of rows.
The problem that I'm getting only the first row with id = 1, and it seems that the count number is correct.
So the result should by something like that:
['count' => 2 , [Newsn1,Newsn2]
Don't tell me to use array_count because I need to get the count of rows in the database, and I have a setMaxResults function, so I will not get a real number of rows.
I don't know the configuration of your table, I just can imagine. So, here's my try:
For getting counts for all titles in your table:
# SQL
SELECT COUNT(id) AS count, GROUP_CONCAT(title SEPARATOR ', ') AS titles FROM newses GROUP BY title
# DQL. assuming you are using a Repository method:
$qb = $this->createQueryBuilder('n');
$qb
->select("COUNT(n.id) AS count, GROUP_CONCAT(n.title SEPARATOR ', ') AS titles")
->leftJoin('n.category', 'c')
->groupBy('n.title')
;
return $qb->getQuery()->getArrayResult();
For getting counts for a particular title:
# SQL
SELECT COUNT(id) AS count, GROUP_CONCAT(title SEPARATOR ', ') AS titles FROM newses WHERE n.title LIKE '%news%' GROUP BY title
# NewsRepository.php
public function getTitlesCount($title)
{
$qb = $this->createQueryBuilder('n');
$qb
->select("COUNT(n.id) AS count, GROUP_CONCAT(n.title SEPARATOR ', ') AS titles")
->leftJoin('n.category', 'c')
->where('n.title LIKE :title')
->setParameter('title', "%{$title}%")
->groupBy('n.title')
;
return $qb->getQuery()->getArrayResult();
}

count total rows returned by query in doctrine 2 zf2

$countQuery = $qb->select('q.id,d.name,d.numbers')
->from('Application\Entity\quests', 'q');
->leftJoin('q.dots', 'd');
$query1 = $countQuery->getQuery()->getResult();
now how would i get the total number of results returned
**i don't want to write 2 queries** bcz it will increase the execution time than
i have tried
$countQuery = $qb->select('count(q.id) as total_results,d.name,d.numbers')
->from('Application\Entity\quests', 'q');
->leftJoin('q.dots', 'd');
$query1 = $countQuery->getQuery()->getResult();
but its not working
The getResult() method returns an array of results. To count total results returned by getResult() method simply count it with PHP function count.
$countQuery = $qb
->select('q.id,d.name,d.numbers)
->from('Application\Entity\quests', 'q')
->leftJoin('q.dots', 'd');
$query1 = $countQuery->getQuery()->getResult();
$totalResults = count($query1);
If you want to paginate your query then in case of counting total rows you need to execute two queries. One for paginated results and other to count all rows in the database.

Doctrine DQL - sum of orders by brand and by date in one query

I'm working with Symfony 2.
I need to create a DQL query that would provide me with data to be displayed in the this form:
I need the sum of all orders by brand and by year.
The required tables in the database look like this:
Brand:
VOrder:
So far, I have managed to extract a year, order value and a brand for every orderthe following DQL, but this is nowhere close where I want to be:
$query = $em->createQuery(
"SELECT SUBSTRING(o.date, 1, 4), o.value, b.name
FROM AppBundle:VOrder o
LEFT JOIN AppBundle:Brand b WITH b.id = b
GROUP BY o.date"
);
My question boils down to these:
1. Is it possible to achieve the desired result (see the table above) with only one query?
2. Where do I go from here to get the needed data?
This can be done with a single query, but I think it's best to do this without DQL.
The documentation explains the drawbacks of using DQL for aggregate fields
Have a look at how to run native SQL with doctrine in the docs.
The query itself should do a GROUP BY YEAR(date), and a SUM(value):
SELECT
YEAR(o.date),
SUM(o.value),
b.name
FROM brands b
LEFT JOIN orders o
ON o.brand_id = b.id
GROUP BY YEAR(o.date);
With help from my colleague, I managed to find DQL that does exactly what I was looking for:
$query = $em->createQuery(
"SELECT SUBSTRING(o.date, 1, 4) AS year, SUM(o.value), b.name
FROM AppBundle:Brand b
LEFT JOIN AppBundle:VOrder o WITH o.brand = b.id
GROUP BY year, b.id"
);
There is no YEAR() function on DQL, so the workaround was to use SUBSTRING().
You need next query:
$query = $em->createQuery(
"SELECT YEAR(o.date), sum(o.value), b.name
FROM AppBundle:VOrder o
LEFT JOIN AppBundle:Brand b WITH b.id = o.brand_id
GROUP BY YEAR(o.date), b.name"
);

symfony2 doctrine select IFNULL

Ok i have this code:
SELECT
IFNULL(s2.id,s1.id) AS effectiveID,
IFNULL(s2.status, s1.status) AS effectiveStatus,
IFNULL(s2.user_id, s1.user_id) as effectiveUser,
IFNULL(s2.likes_count, s1.likes_count) as effectiveLikesCount
FROM statuses AS s1
LEFT JOIN statuses AS s2 ON s2.id = s1.shared_from_id
WHERE s1.user_id = 4310
ORDER BY effectiveID DESC
LIMIT 15
And i need to rewrite it to querybuilder. Something like that?
$fields = array('IFNULL(s2.id,s1.id) AS effectiveID','IFNULL(s2.status, s1.status) AS effectiveStatus', 'IFNULL(s2.user_id, s1.user_id) as effectiveUser','IFNULL(s2.likes_count, s1.likes_count) as effectiveLikesCount');
$qb=$this->_em->createQueryBuilder()
->select($fields)
->from('WallBundle:Status','s1')
->addSelect('u')
->where('s1.user = :user')
->andWhere('s1.admin_status = false')
->andWhere('s1.typ_statusu != :group')
->setParameter('user', $user)
->setParameter('group', 'group')
->leftJoin('WallBundle:Status','s2', 'WITH', 's2.id=s1.shared_from_id')
->innerJoin('s1.user', 'u')
->orderBy('s1.time', 'DESC')
->setMaxResults(15);
var_dump($query=$qb->getQuery()->getResult());die();
This error is
[Syntax Error] line 0, col 7: Error: Expected known function, got 'IFNULL'
Use COALESCE instead of IFNULL like this
$fields = array('COALESCE(s2.id,s1.id) AS effectiveID','COALESCE(s2.status, s1.status) AS effectiveStatus', 'COALESCE(s2.user_id, s1.user_id) as effectiveUser','COALESCE(s2.likes_count, s1.likes_count) as effectiveLikesCount');
COALESCE return the first value not null in the list, so if A is null and B not null, then COALESCE(A,B) will return B.
There is a Doctrine extension that adds this among others.
This is the DQL file from IFNULL.
https://github.com/beberlei/DoctrineExtensions/blob/master/src/Query/Mysql/IfNull.php
This chapter explains how you use them.
http://symfony.com/doc/2.0/cookbook/doctrine/custom_dql_functions.html

Writing raw query in symfony2 and passing it to pagefanta for pagination

SELECT Inventory_Stock.id, Inventory_Stock.quantity, SUM(InventoryUsage.quantity)
,Inventory_Stock.quantity - SUM(InventoryUsage.quantity) AS Stock
FROM Inventory_Stock LEFT JOIN InventoryUsage ON Inventory_Stock.id = InventoryUsage.InventoryStock_id
WHERE Inventory_Stock.id = 26 OR
Inventory_Stock.id = 27
GROUP BY Inventory_Stock.id
ORDER BY Stock Asc
How can I write the above code in Symfony2, I want to write it as raw query
Also I am using PageFanta for pagination.. so the result from the above query will go to pagination.
Relations are :
Product ( 1 - 1) InventoryStock
InventoryStock ( 1 - n ) InventoryUsage
If it isn't a problem get all records to array. And use ArrayAdapter:
$adapter = new ArrayAdapter($array);
$pagerfanta = new Pagerfanta($adapter);
If the count of the records is too big. Write your own adapter for pagerfanta

Resources