laravel sql queries not working after conversion from regular sql - php

I was wondering if you could look at 3 sql queries followed by the converted JOIN queries that do not work. I keep getting an undefined index error - not sure what i'm doing wrong.
Please note that $db_table_prefix = app_ No big deal.
$db->sql_escape = mysql_real_escape_string (removed b/c laravel does it's own escaping)
1:
OLD:
$sql = "SELECT ".$db_table_prefix."Users.Group_ID,
".$db_table_prefix."Groups.*
FROM ".$db_table_prefix."Users
INNER JOIN ".$db_table_prefix."Groups ON ".$db_table_prefix."Users.Group_ID = ".$db_table_prefix."Groups.Group_ID
WHERE
User_ID = '".$db->sql_escape($this->user_id)."'";
NEW:
return (array)DB::table('app_Users')
->select('app_Users.Group_ID')
->join('app_Groups', 'app_Users.Group_ID', '=', 'app_Groups.Group_ID')
->where('User_ID', '=', $this->user_id)
->first();
2:
Old:
$sql = "SELECT ".$db_table_prefix."Users.Group_ID,
".$db_table_prefix."Groups.* FROM ".$db_table_prefix."Users
INNER JOIN ".$db_table_prefix."Groups ON ".$db_table_prefix."Users.Group_ID = ".$db_table_prefix."Groups.Group_ID
WHERE User_ID = '".$db->sql_escape($this->user_id)."'
AND
".$db_table_prefix."Users.Group_ID = '".$db->sql_escape($db->sql_escape($id))."'
LIMIT 1
";
New:
return (bool)DB::table('app_Users')
->select('app_Users.Group_ID')
->join('app_Groups', 'app_Users.Group_ID', '=', 'app_Groups.Group_ID')
->where('User_ID', '=', $this->user_id)
->where('app_Users.Group_ID', '=', $id)
->first();
3.
Old:
$sql = "SELECT ".$db_table_prefix."Users.Group_ID,
".$db_table_prefix."Groups.*
FROM ".$db_table_prefix."Users
INNER JOIN ".$db_table_prefix."Groups ON ".$db_table_prefix."Users.Group_ID = ".$db_table_prefix."Groups.Group_ID
WHERE
User_ID = '".$db->sql_escape($userId)."'";
New:
return (array) DB::table('app_Users')
->select('app_Users.Group_ID')
->join('app_Groups', 'app_Users.Group_ID', '=', 'app_Groups.Group_ID')
->where('User_ID', '=', $userId)
->first();
Thanks!

Related

SQLSTATE[23000]: Integrity constraint violation: 1052. Laravel eloquent issue when joining table

I have News table and the column in the blade table posted by is empty but in my news table the column users_id which is the posted by has a users_id value. I cant get the user who posted the specific news in specific school. I already have a working query for the news, but the problem is i cant join the users table where the name of the user who posted the news is in there. Can someone know what are the problem of my query? Help will be appreciated. Thanks
Index controller
public function index()
{
//testing query that returns an error
$userschool = Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where('school_id', Auth::user()->school_id)->get();
//the query that i want still returns an error because of the auth
$postedby = DB::select(
"SELECT news.*, users.name as postedby from news
JOIN users on news.users_id = users.id
WHERE news.school_id AND news.active = 1 AND news.school_id = 'Auth::user()->school_id'");
//working queries and i dont know how to convert the $postedby query join to eloquent.
if (Auth::user()->role == 0) {
$news = Newsboard::where('active','=',1)->get();
} elseif (Auth::user()->role == 1 || Auth::user()->role == 5) {
$news = Newsboard::where('school_id', '=', Auth::user()->school_id )
->where('active','=',1)
->get();
} else {
$role = Auth::user()->role;
$news = Newsboard::where('school_id', '=', Auth::user()->school_id )
->where('status', '=', 1)
->where('active','=',1)
->whereRaw("group_id in('$role', '0')")
->get();
}
dd($userschool);
return view('admin.pages.news.index', [
'page_title' => $this->page_title,
'news' => $news,
'mnuname' => 'News',
]);
}
Set your Auth::user()->school_id as variable
$school_id = Auth::user()->school_id;
//the query that i want still returns an error because of the auth
$postedby = DB::select(
"SELECT news.*, users.name as postedby from news
JOIN users on news.users_id = users.id
WHERE news.school_id AND news.active = 1 AND news.school_id = '$school_id'");
Or this:
Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where(['news.school_id' => $school_id])->get();
Because both users and news table contain school_id column, so in where condition must has table prefix.
Please try:
$userschool = Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where('news.school_id', Auth::user()->school_id)->get();
//or
//the query that i want still returns an error because of the auth
$postedby = DB::select("SELECT news.*, users.name as postedby from news
JOIN users on news.users_id = users.id
WHERE news.school_id AND news.active = 1 AND news.school_id = '".Auth::user()->school_id."'");
$school_id = Auth::user()->school_id;
$userschool = Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where('school_id', $school_id)->get();

select all columns which are not in another table laravel 5.5

I have two tables - the first one is called 'users' and the second one is called 'buy_courses'.
I am trying to select all users those user_name is not in buy_courses. I tried something like -
$users = DB::table('users')
->rightjoin('buy_courses', 'users.user_name', '=', 'buy_courses.user_name')
->get();
It returns all users, whose user_name is in 'buy_courses', when I am using '<>', then I'm getting all users. What should be the right query?
DB::table("users")->select('*')->whereNotIn('user_name',function($query) {
$query->select('user_name')->from('buy_courses');
})->get();
just join actually is inner join in Laravel so actually maybe also you can try:
DB::table('users')
->join('buy_courses', 'users.user_name', '=', 'buy_courses.user_name')
->get();
Try it using Eloquent:
$courseUserNames = BuyCourses::pluck('user_name')->all();
$users = User::whereNotIn('user_name', $courseUserNames)->select(...)->get();
Or if you prefer using DB query:
$courseUserNames = DB::table('buy_courses')->pluck('user_name')->all();
$users = DB::table('users')->whereNotIn('user_name', $courseUserNames)->select(...)->get();
just replace = with != , use function join
$users = DB::table('users')
->join(
'buy_courses',
function ($join)
{$join->on('users.user_name', '!=', 'buy_courses.user_name');}
)
->get();
You can use SQL's 'NOT IN'.
Example:
mysqli_query($con, "SELECT * FROM users WHERE user_name NOT IN (SELECT user_name FROM buy_courses)");

Convert mysql query into Eloquent laravel query

I am trying to make the following query in laravel:
SELECT a.name AS subname, a.area_id, b.name, u. id, u.lawyer_id,u.active_search,
FROM subarea a
LEFT JOIN user_subarea u ON u.subarea_id = a.id
AND u.user_id = ?
LEFT JOIN branch b ON a.area_id = b.id
The idea is to obtain the subareas and see if the search is activated by the user.
The user_subarea table might have a record that matches the id of the subarea table where the active_search is equal to 0 or 1. If it doesn't exist I would like the query to return null.
While I was able to achieve this in raw SQL when I try the same with eloquent in Laravel I am not returning any value. I have done the following:
$query = DB::table('subarea')
->join('user_subarea', function($join)
{
$value = \Auth::user()->id;
$join->on( 'subarea.id', '=', 'user_subarea.subarea_id')->where('user_subarea.user_id', '=',$value);
})
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('branch.name', 'subarea.name as subarea', 'user_subarea.active_search_lawyer', 'user_subarea.id' )
->get();
Any help will be much appreciated.
I found by myself the answer it was just to add a lefjoin in the first join. It is not in the laravel docs but works too.
$query = DB::table('subarea')
->lefjoin('user_subarea', function($join)
{
$value = \Auth::user()->id;
$join->on( 'subarea.id', '=', 'user_subarea.subarea_id')->where('user_subarea.user_id', '=',$value);
})
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('branch.name', 'subarea.name as subarea', 'user_subarea.active_search_lawyer', 'user_subarea.id' )
->get();
Try this one, If you get a problem, please comment.
$value = \Auth::user()->id;
$query = DB::table('subarea')
->where('user_subarea.user_id', '=',$value)
->leftJoin('user_subarea', 'subarea.id', '=', 'user_subarea.subarea_id')
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('subarea.name AS subname','subarea.area_id', 'branch.name', 'user_subarea.id','user_subarea.lawyer_id','user_subarea.active_search')
->get();

Query from two tables laravel with multiple conditions

I'm trying to write this query in Laravel query
SELECT
table1.*, table2.*
FROM
table1
LEFT JOIN
table2
ON
(table1.id = table2.id AND (table2.field = '' OR table2.field >= '0'))
WHERE
table.id = id
I have problem with how to add inner part AND ( ... ) to the query? Here is what I have so far
$query = Table::select(
DB::Raw('table1.*, table2.*'))
->leftJoin('table2', function($join) {
$join->on('table1.id', '=', 'table2.id')
->where('table2.field', '=', '')
->orwhere('table2.field', '=', '50');
})->where('table1.id', BaseController::getCurrentUser()->id)
->get();
I miss where and how to add AND ...
Do you need to have the AND part as part of ON? If you move it to the WHERE part of your query you could use something like:
$query = Table::select('table1.*', 'table2.*')
->leftJoin('table2', 'table1.id', '=', 'table2.id')
->where('table1.id', BaseController::getCurrentUser()->id)
->where(function ($query){
$query->where('table2.field', '')
->orWhere('table2.field', 50)
});
The result should be the same as from your original query.

Very slow eloquent query

I have a query in one of my controller in my Laravel controllers that looks like this,
$project = new Project;
$me = ResourceServer::getOwnerId();
$my_projects = Project::ManagedByMe($me)
->OwnedByOrganisationIAmIn($me)
->IAmACollaborator($me)
->NoArchived()
->get(array(
'projects.id',
'projects.name',
'projects.description',
'projects.total_cost',
'projects.sales_person',
'projects.slug',
'projects.uri_hash',
'projects.client_id',
'projects.start_date',
'projects.finish_date',
'projects.organisation_id',
'projects.locked_by',
'projects.created_at',
'projects.status',
'projects.owner_id',
'projects.user_id',
'projects.archived_at'
));
$my_projects->load('projectmanager');
$my_projects->load('clients');
$my_projects->load('organisations')->load('organisations.users');
$my_projects->load('collaborators');
$my_projects->load('status');
$my_projects->load('notifications')->load('notifications.user');
$my_projects->load(array('projectview'=>function($query){
$query->where('users.id','=',ResourceServer::getOwnerId());
})); 
It returns 898 rows of data, and takes over a minute to execute. I am using scopes in the query, that look like this,
public function scopeManagedByMe($query, $user_id) {
$query->distinct();
$query->leftJoin('project_managers', 'projects.id', '=', 'project_managers.project_id');
$query->where('project_managers.user_id', '=', $user_id);
}
public function scopeOwnedByOrganisationIAmIn($query, $user_id) {
$query->leftJoin('organisations', 'projects.organisation_id', '=', 'organisations.id');
$query->leftJoin('organisation_user', 'organisations.id', '=', 'organisation_user.organisation_id');
$query->orWhere('organisation_user.user_id', '=', $user_id);
}
public function scopeIAmACollaborator($query, $user_id) {
$query->leftJoin('collaborators', 'projects.id', '=', 'collaborators.project_id');
$query->orWhere('collaborators.user_id', '=', $user_id);
}
public function scopeNoArchived($query) {
$query->orWhere('projects.archived_at', '=', '0000-00-00 00:00:00');
$query->whereNull('projects.deleted_at');
}
and the SQL that is actually run looks like this,
select distinct `projects`.`id`,
`projects`.`name`,
`projects`.`description`,
`projects`.`total_cost`,
`projects`.`sales_person`,
`projects`.`slug`, `projects`.`uri_hash`,
`projects`.`client_id`,
`projects`.`start_date`, `projects`.`finish_date`,
`projects`.`organisation_id`,
`projects`.`locked_by`, `projects`.`created_at`,
`projects`.`status`,
`projects`.`owner_id`,
`projects`.`user_id`,
`projects`.`archived_at`
from `projects`
left join `project_managers` on `projects`.`id` = `project_managers`.`project_id`
left join `organisations` on `projects`.`organisation_id` = `organisations`.`id`
left join `organisation_user` on `organisations`.`id` = `organisation_user`.`organisation_id`
left join `collaborators` on `projects`.`id` = `collaborators`.`project_id`
where `projects`.`deleted_at` is null
and `project_managers`.`user_id` = ? or `organisation_user`.`user_id` = ?
or `collaborators`.`user_id` = ? or `projects`.`archived_at` = ?
and `projects`.`deleted_at` is null
What I am trying to do, is select all the projects that I belong to, either by virtue that I am in an organisation that owns a project, I am project manager of the project or a collaborator of the project.
At first set indexes on join-condition fields:
`projects`.`id`
`projects`.`organisation_id`
`project_managers`.`project_id`
`organisations`.`id`
`organisation_user`.`organisation_id`
`collaborators`.`project_id`
if some of them are not setted.
Then update your query execution time in question subject.

Categories