Group by month producing error in laravel controller - mysql

I am trying to execute mysql query
SELECT COUNT( * ) FROM `Mytable` WHERE `col1` = 'value' GROUP BY MONTH(Date_time)
Laravel statement for the same is :
DB::table('Mytable')->where('col1','value')->GroupBy(MONTH('Date_time'))->count();
As query is fine but getting error :
Call to undefined function App\Http\Controllers\MONTH()
Any suggestion will be helpful

Instead of:
->GroupBy(MONTH('Date_time'))
try
->groupBy(DB::raw("MONTH('Date_time')"))
as MONTH() is a mysql function, not laravel function.

This would be your code:
DB::table('Mytable')->where('col1','value')
->groupBy(function($date) {
return Carbon::parse($date->Date_time)->format('m'); // grouping by months
})
->count();
Hope this works!

Related

Laravel select is not working with subquery

I was trying to write laravel function to execute query given below. But i am not getting any result. Please help..
Here is my query
SELECT leads_followup_status_list.followup_status_name, COUNT(FUP.followup_status) FROM leads_enquiry_details LEFT JOIN (SELECT max(followup_id) as FID,leads_enquiry_details_enquiry_id as LID,leads_followup_details.followup_comment,followup_date,followup_status from leads_followup_details WHERE leads_followup_details.followup_deleted=1 GROUP by LID )fup on leads_enquiry_details.enquiry_id=fup.LID JOIN leads_followup_status_list on leads_followup_status_list.followup_status_id =FUP.followup_status where leads_enquiry_details.enquiry_deleted=1 and leads_enquiry_details.enquiry_status=1 GROUP by FUP.followup_status
This is my function
public function getFollowupStatusCount($parametr=null){
$status_counts = LeadsDetails::where('enquiry_deleted', '=', 1)
->where('enquiry_status', 1)
->leftjoin(DB::raw('(SELECT max(followup_id) as FID,leads_enquiry_details_enquiry_id as LID,
leads_followup_details.followup_comment,
followup_date,followup_status from leads_followup_details GROUP by LID )
FUP'),
function($leftjoin)
{
$leftjoin->on('leads_enquiry_details.enquiry_id', '=', 'fup.LID');
})
->leftjoin('leads_followup_status_list.followup_status_id','leads_followup_status_list','fup.followup_status')
->select('COUNT(FUP.followup_status) as count', 'leads_followup_status_list.followup_status_name as status',
'leads_followup_status_list.followup_status_color_code as color')
->groupBy('followup_status');
return $status_counts;
}
Ok so I've noticed 2 problems. First, you miss ->get() at the end of you request. Second, your parameters order is wrong on second leftJoin. Should be:
->leftJoin('leads_followup_status_list',
'leads_followup_status_list.followup_status_id', '=', 'fup.followup_status')
Should work after these fixes.
Thank you very much #Pavel Lint, There were one mistake too . I should have used select( DB::raw('count(FUP.followup_status) as count'),' instead of count..

nested queries in laravel

Here is my sql, i am struggling to translate this to laravel 5.8 query builder syntax.
SELECT CC AS CountOfVisits, Count(CC) AS Users
FROM
(
SELECT user_id, count(user_id) AS CC FROM mytable
GROUP BY user_id
) AS CC
GROUP BY CC;
I tried this:
$frequency= DB::connection('mysql2')
->select(DB::raw('CC AS CountOfVisits'), DB::raw('Count(CC) AS Users'))
->from(function($sq)
{
$sq->select(DB::raw('user_id, count(user_id) AS CC FROM '))
->from('mytable')
->groupBy('user_id');
})
->groupBy('CC')
->get();
it errors with
Argument 1 passed to Illuminate\Database\Connection::prepareBindings()
must be of the type array, object given, called in
/var/app/portal/vendor/laravel/framework/src/Illuminate/Database/Connection.php
on line 665
Any help would be great thanks
I think the problem you're having is that the returned connection is expecting string for the full query with additional bindings on the second parameter. You can still build it using illuminate's query builder first if you like, then run the select using the generated string.
$query = DB::query()
->select('CC AS CountOfVisits', DB::raw('count(CC) AS Users'))
->fromSub(function (\Illuminate\Database\Query\Builder $query) {
$query->select('user_id', DB::raw('count(user_id) AS CC '))
->from('mytable')
->groupBy('user_id');
}, 'CC')
->groupBy('CC');
$result = DB::connection()->select($query->toSql());

How to select DB Expression as value using knex/Bookshelf

I'm trying to execute the following query using knex.js and MySql
SELECT
m.id,
TIME(date_created) AS `timestamp`,
u.username,
m.`message`
FROM
`messages` AS m
INNER JOIN users AS u ON u.id = m.user_id
WHERE
m.game_id IS NULL
AND m.`date_created` > DATE_SUB(
CURRENT_TIMESTAMP (),
INTERVAL 12 HOUR
)
ORDER BY
m.`date_created` ASC
LIMIT 50
For proper handling expressions in where closure such as DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR) according to documentation there is whereRow() method in knex.
I tried to use select() method as
select('messages.id', 'TIME(date_created) AS timestamp', 'users.username', 'messages.message')
But knex masks TIME(date_created) expression in a way it should to be a column name. Does anybody know a way to use a custom expressions in selects?
I did not found exact answer on my question but I've found a solution which allows me to move forward. I created separate model which uses standard Bookshelf(knex) export:
var Bookshelf = require('bookshelf')(knex);
module.exports.DB = Bookshelf;
And created separate method in that model where I could use DB.knex.raw() for masking DB expressions in SELECT. So I became able to write the query above in the following way:
var DB = require('./../db').DB;
var Messages = DB.Model.extend({
tableName: 'messages',
hasTimestamps: false,
idAttribute: 'id'
},
{
getMessagesHistory: function (gameId) {
return this.query().select('messages.id', DB.knex.raw('TIME(date_created) AS timestamp'), 'users.username', 'messages.message')
.innerJoin('users', 'messages.user_id', 'users.id')
.whereRaw("messages.game_id " + (gameId == 0 ? "IS NULL" : "= " + gameId))
.andWhereRaw("messages.date_created > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR)")
.orderBy('messages.date_created', 'ASC')
.limit(50);
}
}
);
module.exports = Messages;
You can wrap any argument with knex.raw() to tell the framework that it's a raw piece of SQL:
select(
'messages.id',
knex.raw('TIME(date_created) AS timestamp'),
'users.username',
'messages.message',
)
See http://knexjs.org/#Raw-Bindings

Doctrine 1 select column with duplicate values

I have a query that will display columns with duplicate or with more than 1 values.I can display it using sql
select date_created,loan_id,count(1) as cnt
from collections
group by date_created,loan_id
having count(1)>1;
I want that to convert to Doctrine 1 query,I tried
public function getDuplicateDatePayment() {
$q = $this->createQuery('c')
->select('c.date_created,c.loan_id,c.count(1) as cnt')
->groupBy('c.date_created','c.loan_id')
->having('c.count(1) > 1');
return $q->execute();
}
But it only return errors.Any Idea on how to correctly convert the said working sql into a doctrine 1 query?
SQLSTATE[42000]: Syntax error or access violation: 1630 FUNCTION c.count does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual. Failing Query: "SELECT c.id AS c__id, c.date_created AS c__date_created, c.loan_id AS c__loan_id, c.count(1) AS c__0, c.count(1) AS c__0 FROM collections c GROUP BY c.date_created HAVING c.count(1) > 1"
I hope the problem may be with count. Try the following
public function getDuplicateDatePayment() {
$q = $this->createQuery('c')
->select('c.date_created,c.loan_id,count(c.1) as cnt')
->groupBy('c.date_created','c.loan_id')
->having('c.count(1) > 1');
return $q->execute();
}

How to group by SqlFunction with VarArgsSQLFunction in NHibernate

I'm trying to implement the following SQL query with QueryOver:
SELECT [Time]/1000
FROM TableName
GROUP BY [Time]/1000
Here's my current attempt:
var result = session
.QueryOver<TableName>
.Select(Projections.GroupProperty(
Projections.SqlFunction(
new VarArgsSQLFunction("(", "/", ")"),
NHibernateUtil.Int64,
Projections.Property("Time")
Projections.Constant(1000))
))
.List<object>();
Unfortunately I get the following exception (GenericADOException):
could execute query
[ SELECT (this_.Time/#p0) as y0_ FROM [TableName] this_ GROUP BY (this_.Time/?) ]
And the inner exception:
Incorrect syntax near ?.
I can replace the "GroupProperty" with a "Sum" and it works. Any idea what's missing?
Update:
Apparently it's a bug in NHibernate. See also this question.
Why don't you just use Projections.SqlGroupProjection:
var result = session
.QueryOver<TableName>
.Select(Projections.SqlGroupProjection(
Time/1000 AS TimeValue",
"Time/1000",
new[]{"TimeValue"},
new[]{NHibernateUtil.Int32}))
.List<object>();