How to write mysql query in laravel 5.4? - php

I am new to laravel and i want to write mysql query in laravel 5.4.
query is like :
note: avoid column names..
SELECT *
FROM (SELECT DISTINCT *
FROM messages
WHERE (from_id=1 OR to_id=1)
ORDER BY created DESC) as m
GROUP BY `from_id`
I tried but gives error.
$messages = DB::table('messagetbl')
->select('*')
->Where(function($query) use ($userid){
$query->distinct()
->where('senderid',$userid)
->orWhere('receiverid',$userid)
->orderBy('datetime','desc');
})
->groupBy('senderid')
->get();
Error:
SQLSTATE[42000]: Syntax error or access violation: 1055
Expression #1 of SELECT list is not in GROUP BY clause and contains
nonaggregated column 'db.messagetbl.id' which is not functionally
dependent on columns in GROUP BY clause; this is incompatible with
sql_mode=only_full_group_by (SQL: select * from messagetbl where
(senderid = 8 or receiverid = 8) group by senderid)
Thanks in advance.

I believe something like this:
DB::table('messages')
->select('*')
->where('form_id', '=', 1)
->orWhere('to_id', '=', 1)
->orderBy('created', 'desc')
->groupBy('form_id')
->distinct()
->get();

Related

Why am is laravel throwing an SQLSTATE[42000]: Syntax error or access violation: 1064 Error

Am running a query builder on my laravel app using inner join
But Laravel keeps throwing errors, i tested the MySql Query
i wrote directly in my database using phpMyAdmin it works fine
SELECT
u.id, u.first_name, u.last_name, u.username, u.sponsor,u.deleted_at, i.id as investment_id, i.total_amount, i.created_at
FROM
users AS u
JOIN investments as i ON
i.id= ( SELECT i1.id FROM investments as i1 where u.id=i1.user_id and i1.status ='confirmed' ORDER BY i1.created_at LIMIT 1)
WHERE
u.sponsor = '901d08da-e6c4-476a-ae7b-9386990b8b9e' AND u.deleted_at is NULL
ORDER BY
created_at DESC
but when i write it using query builder it wont work.
$refered_users = DB::table('users')
->join('investments', function ($join) {
$join->on('users.id', '=', 'investments.user_id')
->where('investment.status', '=', 'confirmed')
->orderBy('investment.created_at','desc')->first();
})
->select('users.id,users.first_name,users.last_name,users.username,users.sponsor,investment.id AS investment_id,investment.total_amount,investment.created_at')
->where('users.sponsor','=',Auth::User()->id)
->orderBy('investment.created_at','desc')
->paginate(10);
i tried a RAW DB::select() and it works but i want to use the query builder so i can paginate the results.
this is how my table is arranged:
users
id, first_name, last_name, username, sponsor(id of another user), created_at, deleted_at
investments
id, total_amount , user_id(id of a user), status, created_at, deleted_at
Am not much Good with SQL Queries so if am writing it all wrong please don't scold just, try to explain a lil bit more so i can understand
this is the error coming out:
Illuminate\Database\QueryException
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near 'on users.id = investments.user_id and
investment.status = ? order by' at line 1 (SQL: select * on
users.id = investments.user_id and investment.status =
confirmed order by investment.created_at desc limit 1)
output of the dd
select first_name,last_name,username,deleted_at,total_amount,
investment_created_at,user_id from `users`
inner join (select user_id,total_amount,status,created_at AS investment_created_at from `investments`
where `status` = ? and `investments`.`deleted_at` is null) as `confirmed_investments`
on `users`.`id` = `confirmed_investments`.`user_id`
where `sponsor` = ? order by `investment_created_at` desc ◀`
`array:2 [▼ 0 => "confirmed" 1 => "901d08da-e6c4-476a-ae7b-9386990b8b9e" ]`
am using:
PHP version: 7.3.1
MySql Version: 8.0.18
You can get query of your code and compare it to your desired query like this:
$refered_users = DB::table('users')
->join('investments', function ($join) {
$join->on('users.id', '=', 'investments.user_id')
->where('investment.status', '=', 'confirmed')
->orderBy('investment.created_at','desc')->first();
})
->select('users.id,users.first_name,users.last_name,users.username,users.sponsor,investment.id AS investment_id,investment.total_amount,investment.created_at')
->where('users.sponsor','=',Auth::User()->id)
->orderBy('investment.created_at','desc')
->toSql();
Your join query is getting data for id by running another query. I think you need to use sub query. If you are using laravel > 6 it is on documentation.

How Get Count in Join Query in Laravel

I want to convert the following SQL to Laravel.
SELECT COUNT('uc.*') AS count_down, bs.brand_name
FROM `user_activities` AS uc
JOIN brands AS bs ON uc.brand_id = bs.id
GROUP BY uc.brand_id
ORDER BY count_down DESC
LIMIT 5
But when doing this:
$top_donwload_list = DB::table('user_activities')
->leftJoin('brands', 'brands.id', '=', 'user_activities.brand_id')
->selectRaw('brands.*, brands.brand_name, brands.id, count(user_activities.action_type) as user_activitiesCount')
->groupBy('user_activities.brand_id')
->get();
I get this error:
SQLSTATE[42000]: Syntax error or access violation: 1055 'colorworld.brands.id' isn't in GROUP BY (SQL: select brands.*, brands.brand_name, brands.id, count(user_activities.action_type) as user_activitiesCount from user_activities left join brands on brands.id = user_activities.brand_id group by user_activities.brand_id)
I tried to set 'strict' => true, in database.php but I get the same error in Laravel 5.7.
Update:- database table
If I understood your question correctly, you are trying to find the count of user activities grouped by a brand's name. Also you want the top 5 records ordered by the ones with the most user activities.
So, the following should work:
$top_donwload_list = DB::table('user_activities')
->selectRaw("brands.brand_name, COUNT('user_activities.*') as user_activitiesCount")
->join('brands', 'brands.id', '=', 'user_activities.brand_id')
->groupBy('brands.brand_name')
->orderBy('user_activitiesCount', 'desc')
->take(5)
->get();
You can use Laravel Eloquent. I Assume that the relationship between brand and user_activities is one to many and Here, the "Brand" is the model of the brand entity.
$count = Brand::leftJoin
('user_activities', function($join_brands){
$join_brands-> on
('brands.id', '=','user_activity.brand_id');
)->orderBy('user_activities.count_down','desc ')
->groupBy('user_activities.brand_id')->count();

Adding raw query to eloquent relationship

I am developing an application in Laravel 5.6 I'm having a simple table with following columns:
company_id project_id company_role_id company_specialisation_id
And this represents the model AssociateCompanies, which has relation of company, project, role, specialisation now I am having some query to get the attribute:
$companies = AssociateCompany::whereHas('company', function ($q) use ($request) {
$q->whereHas('projectOwners', function ($q) use($request) {
$q->where('slug', $request->slug);
});
})->groupBy('company_id', 'company_specialisation_id')->with('company', 'role', 'specialisation');
I want to collect all unique fields with their counts from two columns company_id and specialisation_id, but groupBy is not giving me proper the results so I am unbale to proceed further:
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'conxn.project_associate_company.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by (SQL: select * from project_associate_company where exists (select , (select count() from project_associate_company where companies.id = project_associate_company.company_id and project_associate_company.deleted_at is null) as associated_projects_count from companies where project_associate_company.company_id = companies.id and exists (select * from projects inner join project_owner_relation on projects.id = project_owner_relation.project_id where companies.id = project_owner_relation.company_id and slug = lodha-patel-estate-tower-a-b-mumbai and projects.deleted_at is null) and companies.deleted_at is null) and project_associate_company.deleted_at is null group by company_id, company_specialisation_id)"
So I tried running raw queries like this:
$companies = AssociateCompany::whereHas('company', function ($q) use ($request) {
$q->whereHas('projectOwners', function ($q) use($request) {
$q->where('slug', $request->slug);
});
})->selectRaw(DB::raw('COUNT(*) AS count GROUP BY company_id , company_specialisation_id'))
->with('company', 'companyRole', 'specialisation')->get();
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY company_id , company_specialisation_id from project_associate_company' at line 1 (SQL: select COUNT(*) AS count GROUP BY company_id , company_specialisation_id from project_associate_company where exists (select , (select count() from project_associate_company where companies.id = project_associate_company.company_id and project_associate_company.deleted_at is null) as associated_projects_count from companies where project_associate_company.company_id = companies.id and exists (select * from projects inner join project_owner_relation on projects.id = project_owner_relation.project_id where companies.id = project_owner_relation.company_id and slug = lodha-patel-estate-tower-a-b-mumbai and projects.deleted_at is null) and companies.deleted_at is null) and project_associate_company.deleted_at is null)"
Suggest me better way to get this. Thanks.
Initially I want to notice you can not "group by" inside the "select" statement.
So you can not aggregate the non-aggregated columns. This means is grouped fields can be has got multiple "role" so you can not "load" the "roles". The query should be like the one of the follows:
AssociateCompany::whereHas('company', function ($q) use ($request) {
$q->whereHas('projectOwners', function ($q) use($request) {
$q->where('slug', $request->slug);
});
})->select('company_id', 'company_specialisation_id', \DB::raw('COUNT(*) as cnt'))
->groupBy('company_id', 'company_specialisation_id')
->with('company', 'specialisation');
Or :
AssociateCompany::whereHas('company', function ($q) use ($request) {
$q->whereHas('projectOwners', function ($q) use($request) {
$q->where('slug', $request->slug);
});
})->select('company_id', 'company_specialisation_id', 'company_role_id', \DB::raw('COUNT(*) as cnt'))
->groupBy('company_id', 'company_specialisation_id', 'company_role_id')
->with('company', 'specialisation', 'role');
My suggestions are like this but I think you can solve it with raw MySQL queries rather than use to Eloquent.

YEAR(begin_date) unknown column in laravel

SELECT COUNT(*) as count, MONTH(begin_date)
FROM `events`
WHERE (YEAR(begin_date) = YEAR(CURDATE()))
OR (YEAR(begin_date) = YEAR(CURDATE()) + 1)
GROUP BY MONTH(begin_date)
Here is sql query, i want to write it in laravel eloquent.
what i try:
$oncoming_events = DB::table('events')
->select(DB::raw('count(*) as numOfOncomingEvents, MONTH(begin_date)'))
->where('YEAR(begin_date)', '=', 'YEAR(CURDATE())')
->orWhere('YEAR(begin_date)', '=', 'YEAR(CURDATE()) +1')
->groupBy('MONTH(begin_date)')->get();
Error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'YEAR(begin_date)' in 'where clause' (SQL: select count(*) as numOfOncomingEvents, MONTH(begin_date) from events where YEAR(begin_date) =
laravel 5.6
btw
sql query works..
You need to use DB::raw() in where to tell the query builder that it is not column name it is data manipulation in query,
$oncoming_events = DB::table('events')->select(DB::raw('count(*) as numOfOncomingEvents, MONTH(begin_date)'))->where(DB::raw('YEAR(begin_date)'), '=', 'YEAR(CURDATE())')->orWhere(DB::raw('YEAR(begin_date)'), '=', 'YEAR(CURDATE()) +1')->groupBy(DB::raw('MONTH(begin_date)'))->get();

Comparing timestamps from two different tables in Laravel 5

I am trying to get results out of union by showing only results that were updated after I last checked (defined by $last_check)
$last_check = CheckNotifications::where('notif_check_user_id', '=', $user_id)->pluck('updated_at');
$get_projects = DB::table('requests')
->join('notifications', 'notifications.notif_project_id', '=', 'requests.id')
->select(DB::raw('requests.updated_at, requests.request_name, "" as fullname, "P" as flag'))
->where('notif_user_id', '=', $user_id)
->whereRaw('requests.updated_at > requests.created_at');
$comments = DB::table('project_comments')
->leftJoin('users', 'comment_user_id', '=', 'users.id')
->leftJoin('requests', 'comment_project_id', '=', 'requests.id')
->select(DB::raw('project_comments.updated_at, requests.request_name, users.fullname, "C" as flag'));
$get_notifications = $get_projects->union($comments)
->whereRaw('updated_at > $last_check')
->orderBy('updated_at', 'desc')
->get();
The union works just fine until I add that last whereRaw statement. With the statement added, I get a SQL Syntax/Access error (#42000). I think it has something todo with the plucking of updated_at for the comparison. Any ideas? Thanks in advance!
Edit: Here's the error code
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '15:09:06) union (select project_comments.updated_at, requests.id as request_id, ' at line 1 (SQL: (select requests.updated_at, requests.id as request_id, requests.request_name, "" as fullname, "P" as flag from `requests` inner join `notifications` on `notifications`.`notif_project_id` = `requests`.`id` where `notif_user_id` = 1 and requests.updated_at > requests.created_at and requests.updated_at > 2015-07-29 15:09:06) union (select project_comments.updated_at, requests.id as request_id, requests.request_name, users.fullname, "C" as flag from `project_comments` left join `users` on `comment_user_id` = `users`.`id` left join `requests` on `comment_project_id` = `requests`.`id`) order by `updated_at` desc)
there whould be 2 updated_at column , Please attach your error while mentioning something like that again I can't be sure of the reason.
the solution is simply to write the table name before the column name
change
->whereRaw('updated_at > $last_check')
into
->whereRaw('requests.updated_at > $last_check')
and change orederby() to be after the whereRaw()
you had written the right code just few lines before :D
I hope this solve your problem
add that whereRaw clause for each of previous two queries
->where('requests.updated_at','>', $last_check)
or
->whereRaw('requests.updated_at > ?', [$last_check])
probably where is not available with union
just curious : if this is working?
$get_notifications = $get_projects->union($comments)
->where(function($query) use ($last_checked){
$query ->where('requests.updated_at','>', $last_check);
})
->orderBy('requests.updated_at', 'desc')
->get();

Categories