I need to find the total number of logins per day, but how would I select count() and group by day in DQL? I'm using Doctrine 2.3.
public function getLoginCount()
{
return $this->createQueryBuilder('i')
->select('i') // and count(*)
->groupBy('i.timestamp') // group by day
->getQuery()
->execute()
;
}
I need something like this:
Date | count
2013-01-01 | 6
2013-01-02 | 7
2013-01-03 | 3
From help on the Doctrine IRC channel you need to create a custom DQL function.
Example:
https://github.com/beberlei/DoctrineExtensions/blob/master/lib/DoctrineExtensions/Query/Mysql/Day.php
Docs:
http://www.doctrine-project.org/blog/doctrine2-custom-dql-udfs.html
A bit late for OP, but maybe someone will find it handy. I was able to achieve that with the DQL query bellow:
$dql = '
SELECT
SUBSTRING(i.timestamp, 1, 10) as date,
COUNT(i) as count
FROM Entity i
GROUP BY date
';
$query = $entityManager->createQuery($dql);
return $query->getResult();
I think similar should be doable with Doctrine query builder.
Related
I have 40 rows in my table, what i want is to get 20 row randomly, and after order these 5 list by id; these 2 in one query;
for example in range of id 1 to 40; i get from the random order 15 10 14 9 3;so in the final result i expect to get 3 9 10 14 15
i tried to use inRandomOrder and orderBy in same time
$query->inRandomOrder()->orderBy('id', 'asc')
but the inRandomOrder query always has the final execution of my query; and if i switch their position:
$query->orderBy('id', 'asc')->inRandomOrder()
the orderBy always has the final execution
2 solutions I guess, if you manipulate only dozens of rows, you can use Laravel collection to order by ID your query result.
Just use:
$result = $query->inRandomOrder()->get();
$resultSortedById = $result->sortBy('id');
Or using SQL query, you can use this query:
SELECT * FROM
(
SELECT * FROM table
ORDER BY RAND()
LIMIT 20
) result
ORDER BY id ASC
You can translate in Eloquent way, or as SQL directly.
I am not sure to understand your question btw: order these 5 list by id ? What do you mean exactly ?
I want a query in laravel to group by data with dateofSale's month with the count of rows with the same month.
here is my table
and I want to output something like this
numberOfSales | Month
2 Nov
1 Oct
how can I do it?
You should be able to achieve this what you're after with:
$data = \App\SaleData::selectRaw('COUNT(*) as count, YEAR(dateOfSale) year, MONTH(dateofSale) month')
->groupBy('year', 'month')
->get();
If you don't include the year as well then you'll have sales from different years included in the same month e.g. sales from October 2017 and October 2018 will be included together.
you can try as
$data = SalesData::select(DB::raw('count('*') as `count`'), DB::raw('MONTH(dateOfSale) month'))
->groupBy(function($m) {
return Carbon::parse($m->dateOfSale)->format('m');
})->get();
don't forget to import carbon and DB on top of your controller like
use DB;
use Carbon\Carbon;
I've been trying to figure this out for some time now and just can't seem to make it work. I have a table that looks similar to this.
Table: Issues
id yearly_issue year stock created_at updated_at magazine_id
1 10 2000 1 [timestamp] [timestamp] 3
2 12 1994 6 [timestamp] [timestamp] 10
3 36 2007 10 [timestamp] [timestamp] 102
4 6 2002 7 [timestamp] [timestamp] 7
5 6 2002 2 [timestamp] [timestamp] 5
6 12 2003 9 [timestamp] [timestamp] 10
7 11 2003 12 [timestamp] [timestamp] 10
My problem is that I need to sort it (easy!) but, I only want to get one of each magazine (column magazine_id).
My Eloquent query as of now is:
$issues = Issue::where('stock', ($all ? '>=' : '>'), 0)
->orderBy('year', 'desc')
->orderBy('yearly_issue', 'desc')
->take($perpage)
->get();
I thought adding the groupBy('magazine_id') would help, but it seems as though it only partially helps me. The results is not in the correct order. So, my question then is - is there any easy way around this?
I've been experimenting with various answers to similar questions but I completely fail to implement it.
Retrieving the last record in each group
or
How to get the latest record in each group using GROUP BY?
More help would be much appreciated.
EDIT:
The closest I am currently is this:
SELECT i1.*, c.name AS image, m.title AS title
FROM issues i1
INNER JOIN covers c ON i1.id = c.issue_id
INNER JOIN magazines m ON i1.magazine_id = m.id
JOIN (SELECT magazine_id, MAX(year) year, MAX(yearly_issue) yearly_issue FROM issues GROUP BY magazine_id) i2
ON i1.magazine_id = i2.magazine_id
AND i1.year = i2.year
-- AND i1.yearly_issue = i2.yearly_issue
WHERE i1.stock ($all ? '>=' : '>') 0
ORDER BY i1.year DESC, i1.yearly_issue DESC
LIMIT $perpage
However, it is not giving me the desired result at all.
You need to add a MAX function in the SELECT clause for each column to be ordered in DESCending order. The inverse goes for columns ordered in ASCending order, you need to add MIN function in the SELECT clause.
Your Eloquent query has to include a raw select:
$issues = DB::table('issues')
->select(DB::raw('id, max(year) as year, max(yearly_issue) as yearly_issue, stock, created_at, updated_at, magazine_id'))
->groupBy('magazine_id')
->orderBy('year', 'desc')
->orderBy('yearly_issue', 'desc')
->take(10)
->get();
The only drawback is that you need to specify each column you want to retrieve. And do not use the * selector, it will override the aggregate function in the select clause.
Update: Seems like adding the * selector before the aggregate functions in the SELECT clause works too. This means that you rewrite the raw select as:
->select(DB::raw('*, max(year) as year, max(yearly_issue) as yearly_issue'))
I think putting the * selector before makes the aggregate functions overrides their columns.
I was looking for a way to order results before grouping and this answer kept popping up. In my case, it was for a user's message inbox. I needed to display the latest message received by the user in each message thread they were part of. My table looks like this:
--------------------------------------------------------------------
| id | sender_id | receiver_id | message | created_at | updated_at |
--------------------------------------------------------------------
| | | | | | |
--------------------------------------------------------------------
The accepted answer on this question, groups the results and then sorts them. I needed to sort the results by the created_at field, descending, before grouping them so I'd get the latest message from each thread. Anyway, here was my final solution after a lot of digging:
$sub = $query->orderBy('created_at', 'desc');
return $query->select('*')
->from(DB::raw("({$sub->toSql()}) as sub"))
->groupBy('sender_id');
This constructs the following query:
select * from (
select * from `messages`
order by `created_at` desc
) as sub
group by `sender_id`
In MySQL you can do something like this:
select *
from `UserTable`
where userId=3
group by `field` desc
order by `dateActivityComplete` ;
In eloquent you would do something like this:
->groupBy('field','desc'), however, ordering the groupBy doesn't seem to be an option in eloquent the same as order by is.
Might be an instance where you have to use a raw query, or possibly the max function.
Wade
first... sorry for my english.
I have a query like this:
Select *
From tableA
Where (
TO_NUMBER(TO_CHAR(dateA(+),'SYYYY')) = 2013
AND TO_NUMBER(TO_CHAR(dateA(+),'MM')) = 02
AND to_number(to_char(dateA(+),'dd')) <= 25
)
and retrieve me the data from each date until last number that I give as parameter, in this case the day 25. This working but delay very much because the form of "Where" statement... anybody know another way that retrieve the data so fast and with the same functionality?
It sounds like you want
SELECT *
FROM tableA
WHERE dateA BETWEEN trunc( date '2013-02-26', 'MM' ) AND date '2013-02-26'
This will return all the rows where dateA is between the first of the month and the specified date. If there is an index on dateA, Oracle would be able to use it for this sort of query (though whether it actually would is a separate issue).
Trying to search between two dates to only get certain rows. A 7 day search.
#date = DateTime.Today
#date2 = //need it to be the prior 7 days
SelectCommand = "SELECT [DateReceived], [DeviceLevel] FROM [TBLReadings] WHERE [DateReceived=#date] <= [DateReceived=#date2] ORDER BY [DateReceived] DESC;
This is wrong but I hope it explain what I am trying to do - only ever used PHP and MySQL.
if you are trying to search between 2 dates, you can use between
the query will be something like
select [dateRecieved], [DeviceLevel] from YourTable where DateReceived between #date and #date2 ORDER BY [DateReceived] DESC
in c#, to get 7 days you can use Datetime.Now.AddDays(7)
http://msdn.microsoft.com/en-us/library/system.datetime.adddays.aspx
sorry for the bad english!
edit: that's only the query, use it as a string in the select command