Laravel 5.2 - Left Join DB::Raw not working? - php

I have the following query where I'm trying to use DB::Raw() for the left join but I'm getting error:
Missing argument 2 for Illuminate\Database\Query\Builder::leftJoin()
This is my query:
return $this->model->from('alerts as a')
->leftJoin(DB::Raw("locations as l on l.id = JSON_UNQUOTE(JSON_EXTRACT(a.criteria, '$.locationId'))"))
->leftJoin(DB::Raw("industries as i on find_in_set(i.id, JSON_UNQUOTE(JSON_EXTRACT(a.criteria, '$.industries')))"))
->where('user_id', '=', $userId)
->selectRaw("a.id
, a.name
, a.criteria
, GROUP_CONCAT(DISTINCT(i.name) SEPARATOR ', ') as 'Industries'
->groupBy('a.id')
->orderBy('a.created_at', 'desc');

The leftJoin function is declared like this:
public function leftJoin($table, $first, $operator = null, $second = null)
You want to pass your raw functions in as the second column:
return $this->model->from('alerts as a')
->leftJoin('locations AS l', 'l.id', '=', DB::Raw("JSON_UNQUOTE(JSON_EXTRACT(a.criteria, '$.locationId'))"))
->leftJoin('industries as i', function($join){
$join->on(DB::raw("find_in_set(i.id, JSON_UNQUOTE(JSON_EXTRACT(a.criteria, '$.industries')))",DB::raw(''),DB::raw('')));
})
->where('user_id', '=', $userId)
->selectRaw("a.id
, a.name
, a.criteria
, GROUP_CONCAT(DISTINCT(i.name) SEPARATOR ', ') as 'Industries'")
->groupBy('a.id')
->orderBy('a.created_at', 'desc');
The find_in_set suggestion came from here.
I'm not sure what '$.locationId' is, but if it's a variable, you can pass that along as a parameter within an array as the second parameter on the DB::raw() function.

Related

join with multiple conditions in Laravel

I'm trying to join two tables using more than one condition. The following query is not working because of the second join condition.
$all_update = DB::table('posts as p')
->join('cprefs as c','p.qatype', '=', 'c.qatype')
->where('c.wwide', '=', 'p.wwide') //second join condition
->where('c.user_id', $u_id)
->where('p.arank', 1)
->get();
The where() functions expects the last parameter to be a parameter where as you are passing in a column name.
To compare two columns you should use the whereColumn method.
With that in mind, you could also write your code like below:
$all_update = DB::table('posts as p')
->join('cprefs as c','p.qatype', '=', 'c.qatype')
->whereColumn('c.wwide', '=', 'p.wwide') //second join condition
->where('c.user_id', $u_id)
->where('p.arank', 1)
->get();
However, this would only work properly if the the join is an INNER JOIN which is true in your case.
The correct method to add multiple join clauses is as below
$all_update = DB::table('posts as p')
->join('cprefs as c', function($q) {
$q->on('p.qatype', '=', 'c.qatype')
->on('c.wwide', '=', 'p.wwide'); //second join condition
})
->where('c.user_id', $u_id)
->where('p.arank', 1)
->get();
Just use this one.
You need the keyword join to use multiple join condition. Irrespective of table.
$all_update = DB::table('posts as p')
->join('cprefs as c','p.qatype', '=', 'c.qatype')
->join('cprefs as c2','p.wwide', '=', 'c2.wwide') //second join condition
->where('c.user_id', $u_id)
->where('p.arank', 1)
->get();

how to write sql query to laravel

i have a sql query like this and i want to convert it to laravel how i can do it?
i have try it, but i confusing on wherein and join
sql query
SELECT MIN(StartFrom) as StartFrom,MAX(EndTo) as EndTo from appointmentsettings
WHERE day=1
and PersonID IN (
SELECT p.id
FROM users p
JOIN appointmentsettings aps ON p.id = aps.PersonID
WHERE p.active=1 AND aps.CompanyID = 1 OR aps.PersonID IN(
SELECT cps.user_id
from companypersonstructs cps
WHERE cps.CompanyID =1
) group by aps.PersonID
)
and active=1
here what i try
Appointmentsetting::select('StartFrom', 'EndTo')
->min('StartFrom')
->max('EndTo')
->where(['Day'=>$day, 'Active'=>1])
->whereIn('PersonID', function ($query) use ($id) {
$query->select('p.id')
->from('users as p')
$query->join('appointmentsettings as aps', 'p.id', '=', '')
->where(["user_id" => $id, 'Active' => 1])->get();
})->orderBy('id')->get();
Appointmentsetting::select('StartFrom', 'EndTo')
->min('StartFrom')
->max('EndTo')
->where(['Day'=>$day, 'Active'=>1])
->whereIn('PersonID', function ($query) use ($id) {
$query->select('p.id')
->from('users as p')
->join('appointmentsettings as aps', 'p.id', '=', '')
->where(["user_id" => $id, 'Active' => 1]);
})->orderBy('id')->get();
You have an error in your join inside the function. Try the above code.
Also you must use get() only at the end of the query and not inside the function itself.
DB Query way
DB::table('appointmentsettings')->join('users','p.id','=','')
->select(DB::raw('MIN(StartFrom) as StartFrom','Max(EndTo) as EndTo'))
->where([['user_id',$id],['Active','1']])
->groupBy('appointmentsettings.PersonID)
->orderBy('id','ASC')
->get();

Laravel 5.4 query builder having issues with groupBy

I'm trying to convert this query to query builder in Laravel 5.4:
SELECT
oc.id,
oc.name,
oat.user_id,
p.first_name,
p.last_name
FROM
oauth_clients oc
LEFT JOIN oauth_access_tokens oat ON oc.id = oat.client_id
JOIN users u on u.id = oat.user_id
JOIN people p on p.id = u.person_id
WHERE oc.revoked = false AND oc.password_client = true
GROUP BY oc.id, oat.user_id
And getting this error barf: Argument 1 passed to Illuminate\Database\Connection::prepareBindings() must be of the type array, string given, called in /var/www/html/source/luniverse/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 648 and defined
This is my attempt at it (one of many):
$tokens = DB::select('oc.id','oc.name','oat.user_id','p.first_name','p.last_name')
->from('oauth_clients as oc')
->leftJoin('oauth_access_tokens as oat', 'oc.id', '=', 'oat.client_id')
->join('users as u', 'u.id', '=', 'oat.user_id')
->join('people as p', 'p.id', '=', 'u.person_id')
->where('oc.revoked', '=', 'false')
->where('oc.password_client', '=', 'true')
->groupBy('oc.id')
->groupBy('oat.user_id')
->get();
The database config is set to strict mode, but that doesn't exactly seem to explain that particular error. The raw query runs fine in a DB gui.
Change the groupby code like
$tokens = DB::select('oc.id','oc.name','oat.user_id','p.first_name','p.last_name')
->from('oauth_clients as oc')
->leftJoin('oauth_access_tokens as oat', 'oc.id', '=', 'oat.client_id')
->join('users as u', 'u.id', '=', 'oat.user_id')
->join('people as p', 'p.id', '=', 'u.person_id')
->where('oc.revoked', '=', 'false')
->where('oc.password_client', '=', 'true')
->groupBy('oc.id','oat.user_id')
->get();
DB::select() executes a query, you have to use DB::table():
DB::table('oauth_clients as oc')
->select('oc.id','oc.name','oat.user_id','p.first_name','p.last_name')

COUNT value mismatch in Eloquent JOIN query of Laravel 5.2

Here is my query
$allInspiration = $allInspiration->select('businesses.id as business_id','businesses.owner_name',
'businesses.user_id as business_user_id','businesses.business_name',
DB::raw("COALESCE(CONCAT(customers.cust_fname, ' ', customers.cust_lname), 'N/A') as customer_name"),
'business_reviews.id as review_master_id','business_reviews.rating',
'business_reviews.comment','business_reviews.review_image',
DB::raw("COUNT(inspiration_likes.id) as like_count"),
DB::raw("COUNT(inspiration_comments.id) as comment_count"),
'business_reviews.customer_id','business_reviews.created_at',
'business_reviews.status')
->join('businesses','business_reviews.business_id', '=', 'businesses.id')
->leftJoin('customers','business_reviews.customer_id', '=', 'customers.id')
->rightJoin('inspiration_likes','business_reviews.id', '=', 'inspiration_likes.review_id')
->rightJoin('inspiration_comments','business_reviews.id', '=', 'inspiration_comments.review_id')
->where('business_reviews.inspiration',1);
The problem is, there are two rows in "inspiration_likes" and two rows in "inspiration_comments". But my like_count and comment_count is both returning 4.
How can I solved this problem?
Use COUNT(DISTINCT) function
COUNT(DISTINCT inspiration_likes.id)
COUNT(DISTINCT inspiration_comments.id)

If using a query builder as to what in the form of its laravel?

I have a query sql like the following may be a bit complex, I am a bit of trouble to convert into a for framework laravel. Please help for everything with framework laravel query results. My problem here is, I do not know how to create a sub select query to laravel framework. Thanks guys.
SELECT
lin_users.status_employee_id,
lin_users.id,
lin_users.username,
lin_users.created,
lin_users.modified,
lin_employee_attributes.unit_code,
lin_employee_attributes.position_code,
lin_employee_attributes.begin_date,
lin_employee_attributes.end_date,
contactnumber.contact_id as phone_number,
contactmobile.contact_id as cell_number,
contactemail.contact_id as email
FROM lin_users
INNER JOIN lin_status_employees
ON lin_users.status_employee_id = lin_status_employees.id
INNER JOIN lin_people
ON lin_status_employees.person_id = lin_people.id
INNER JOIN lin_employee_attributes
ON lin_users.status_employee_id = lin_employee_attributes.status_employee_id
LEFT JOIN lin_contacts AS contactnumber
ON lin_people.id = contactnumber.person_id AND contactnumber.contact_type = 'Work Telephone'
LEFT JOIN lin_contacts AS contactmobile
ON lin_people.id = contactmobile.person_id AND contactmobile.contact_type = 'Mobile'
LEFT JOIN lin_contacts AS contactemail
ON lin_people.id = contactemail.person_id AND contactemail.contact_type = 'Email'
WHERE lin_employee_attributes.begin_date = '2016-11-07'
OR lin_employee_attributes.end_date = '2017-10-21'
GROUP BY lin_users.id,
lin_employee_attributes.unit_code,
lin_employee_attributes.position_code,
lin_employee_attributes.begin_date,
lin_employee_attributes.end_date, lin_people.id,
contactnumber.contact_id,
contactmobile.contact_id,
contactemail.contact_id;
Try this:
const TABLE = 'my_table_name';
return $this
->select(
self::TABLE . 'id as myidalias',
self::TABLE . 'username as myuseralias')
->addSelect(DB::raw(
"
(your custom select here) as mycustomresult
"
));
You can add as many addSelect as you want. Also when you have a lot of complex queries like this, a lot of times you have duplicated parts on them so I highly recommend using scopes it makes your code clean and reusable.
public function scopeLeftJoinCategory($query)
{
return $query
->leftJoin(Category::CONTENTS_CATEGORIES . ' AS cc', 'con.id', '=', 'cc.content_id')
->leftJoin(Category::TABLE . ' AS cat', 'cc.category_id', '=', 'cat.id');
}
Then you just use it like this: ->leftJoinCategory()
Using this work. Finally, with the above query can be solved with the concept query to query in laravel.
$users = $this->db->getTable('users')
->select('users.status_employee_id',
'users.id',
'users.username',
'users.email',
'users.created',
'users.modified',
'users.flag_delete',
'employee_attributes.unit_code',
'employee_attributes.position_code',
'employee_attributes.begin_date',
'employee_attributes.end_date',
'contactnumber.contact_id as phone_number',
'contactmobile.contact_id as cell_number',
'contactemail.contact_id as email'
)
->join('status_employees', 'users.status_employee_id', '=', 'status_employees.id')
->join('people', 'status_employees.person_id', '=', 'people.id')
->join('employee_attributes', 'users.status_employee_id', '=', 'employee_attributes.status_employee_id')
->leftJoin('contacts AS contactnumber', function($join)
{
$join->on('people.id', '=', 'contactnumber.person_id');
$join->on('contactnumber.contact_type','=', DB::raw("'Work Telephone'"));
})
->leftJoin('contacts AS contactmobile', function($join)
{
$join->on('people.id', '=', 'contactmobile.person_id');
$join->on('contactmobile.contact_type','=', DB::raw("'Mobile'"));
})
->leftJoin('contacts AS contactemail', function($join)
{
$join->on('people.id', '=', 'contactemail.person_id');
$join->on('contactemail.contact_type','=', DB::raw("'Email'"));
})
->where(function ($query) use ($begin_date, $end_date) {
$query->where('employee_attributes.begin_date', $begin_date)
->orWhere('employee_attributes.end_date', $end_date);
})
->groupby('users.status_employee_id',
'users.id',
'users.username',
'users.email',
'users.created',
'users.modified',
'users.flag_delete',
'employee_attributes.unit_code',
'employee_attributes.position_code',
'employee_attributes.begin_date',
'employee_attributes.end_date',
'contactnumber.contact_id',
'contactmobile.contact_id',
'contactemail.contact_id'
)
->get();

Categories