I currently have a SQL query which a fantastic stackoverflow member helped me with earlier today. At the moment it works absolutely fine and the way I want it to work.
The only problem is it's RAW SQL and I'd very much like to get this working with the Laravel Query Builder.
SORRY THIS IS AN EDIT - HERE IS THE ORIGINAL QUERY:
$addresses = DB::select(
DB::raw('
(SELECT
"Company" AS object_type_name,
companies.company_name AS object_name,
addresses.*
FROM
addresses
INNER JOIN
companies
ON
addresses.object_id = companies.id
WHERE
addresses.object_type = 2)
UNION ALL
(SELECT
"Job" AS object_type_name,
jobs.job_title AS object_name,
addresses.*
FROM
addresses
INNER JOIN
jobs
ON
addresses.object_id = jobs.id
WHERE
addresses.object_type = 4)
'));
Here is the code I have so far:
$bindings = array(
'soft_deleted' => 0,
'user' => 1,
'company' => 2,
'candidate' => 3,
'job' => 4,
);
$companies = DB::table('addresses')->select(
'addresses.*',
'companies.company_name as object_name'
)->where('addresses.soft_deleted', '=', 0)->join('companies', function($join) use ($bindings){
$join->on('addresses.object_id', '=', 'companies.id')
->where('addresses.object_type', '=', $bindings['company']);
});
$jobs = DB::table('addresses')->select(
'addresses.*',
'jobs.job_title as object_name'
)->join('jobs', function($join) use ($bindings){
$join->on('addresses.object_id', '=', 'jobs.id')
->where('addresses.object_type', '=', $bindings['job']);
});
$addresses = $companies->unionAll($jobs)->get();
With the code above I'm getting the following error:
SQLSTATE[HY093]: Invalid parameter number (SQL: (select addresses., companies.company_name as object_name from addresses inner join companies on addresses.object_id = companies.id and addresses.object_type = 2 where addresses.soft_deleted = 0) union all (select addresses., jobs.job_title as object_name from addresses inner join jobs on addresses.object_id = jobs.id and addresses.object_type = ?))
I've done hours worth of searching but I can't seem to find the answer to this little problem.
I managed to fix it. It was as simple as removing the ->where from within each join closure and chaining it to the join itself and not nesting it.
Before:
$companies = DB::table('addresses')->select(
'addresses.*',
'companies.company_name as object_name'
)->where('addresses.soft_deleted', '=', 0)->join('companies', function($join) use ($bindings){
$join->on('addresses.object_id', '=', 'companies.id')
->where('addresses.object_type', '=', $bindings['company']);
});
$jobs = DB::table('addresses')->select(
'addresses.*',
'jobs.job_title as object_name'
)->join('jobs', function($join) use ($bindings){
$join->on('addresses.object_id', '=', 'jobs.id')
->where('addresses.object_type', '=', $bindings['job']);
});
After:
$companies = DB::table('addresses')->select(
'addresses.*',
'companies.company_name as object_name'
)->where('addresses.soft_deleted', '=', 0)->join('companies', function($join){
$join->on('addresses.object_id', '=', 'companies.id');
})->where('addresses.object_type', '=', 2);
$jobs = DB::table('addresses')->select(
'addresses.*',
'jobs.job_title as object_name'
)->where('addresses.soft_deleted', '=', 0)->join('jobs', function($join){
$join->on('addresses.object_id', '=', 'jobs.id');
})->where('addresses.object_type', '=', 4);
$addresses = $companies->unionAll($jobs)->get();
Hope this helps someone.
Related
i'd like to ask, how would you write the following query in Laravel Eloquent?
Please note the COALESCE, IF, and the complex LEFT JOIN ... ON (... AND ...).
SELECT COALESCE(IF(customer_group_id=6, prices.price, NULL), products.price) AS finalPrice, prices.customer_group_id, products.*, product_translations.*
FROM `product_categories`
LEFT JOIN `products` ON `product_categories`.`product_id` = `products`.`id`
LEFT JOIN `product_translations` ON `product_translations`.`product_id` = `products`.`id`
LEFT JOIN `prices`
ON (`products`.`id` = `prices`.`product_id` AND `prices`.`customer_group_id` = 6 )
WHERE `product_translations`.`locale` = 'it'
AND `products`.`online` = 1
AND `products`.`sellable` = 1
AND `category_id` = 22
UPDATE: By far, what i came up with is the following:
ProductCategory::leftjoin('products', 'product_categories.product_id', '=', 'products.id')
->leftJoin('product_translations', 'product_translations.product_id', 'products.id')
->leftJoin('prices', function($join) use($customer_group_id) {
$join->on('products.id', '=', 'prices.product_id')
->on('prices.customer_group_id', '=', DB::raw($customer_group_id));
})
->select(
DB::raw('coalesce(if(customer_group_id='.$customer_group_id.',prices.price,NULL), products.price) AS finalPrice'),
'prices.customer_group_id',
'products.*',
'product_translations.*'
)
->where('product_translations.locale', '=', $locale)
->where('products.online', '=', true)
->where('products.sellable', '=', true)
->where('category_id', '=', $this->id);
How can I write the query like that on Laravel, btw I'm using DB
I followed this instruction
https://dba.stackexchange.com/questions/175786/join-multiple-tables-for-aggregates, but still not get it
mysql query:
SELECT inptkegiatan.IDKEGIATAN,
(SELECT COUNT(kuesioner.PERTANYAAN)
FROM kuesioner
WHERE inptkegiatan.IDKEGIATAN = kuesioner.IDKEGIATAN) as totalPertanyaan,
(SELECT SUM(hasilkuesioner.JAWABAN)
FROM hasilkuesioner
WHERE kuesioner.IDKEGIATAN = hasilkuesioner.IDKEGIATAN) as totalJawaban,
(SELECT COUNT(regiskegiatan.IDKEGIATAN)
FROM regiskegiatan
WHERE hasilkuesioner.IDKEGIATAN = regiskegiatan.IDKEGIATAN ) as totalUser
FROM inptkegiatan
LEFT JOIN kuesioner ON inptkegiatan.IDKEGIATAN = kuesioner.IDKEGIATAN
LEFT JOIN hasilkuesioner ON inptkegiatan.IDKEGIATAN = hasilkuesioner.IDKEGIATAN
LEFT JOIN regiskegiatan ON inptkegiatan.IDKEGIATAN = regiskegiatan.IDKEGIATAN
GROUP BY inptkegiatan.IDKEGIATAN
I tried this on my Laravel with that url, still not get it
$datatwo = DB::table('inptkegiatan')
->join('kuesioner', 'inptkegiatan.IDKEGIATAN', '=', 'kuesioner.IDKEGIATAN')
->join('hasilkuesioner', 'inptkegiatan.IDKEGIATAN', '=', 'hasilkuesioner.IDKEGIATAN')
->join('regiskegiatan', 'inptkegiatan.IDKEGIATAN', '=', 'regiskegiatan.IDKEGIATAN')
->where('IDNARASUMBER', '=', $value->PROFILEUSERS_ID)
->select('kuesioner.PERTANYAAN', 'hasilkuesioner.*', 'regiskegiatan.*',
DB::raw('count(DISTINCT(kuesioner.IDKEGIATAN)) + SUM(DISTINCT(hasilkuesioner.IDKEGIATAN)) as articles')
)
->groupBy('inptkegiatan.IDKEGIATAN')
->get();
First of all, use leftJoin instead of join, because join is alternate for innerJoin
$datatwo = DB::table('inptkegiatan')
->leftJoin('kuesioner', 'inptkegiatan.IDKEGIATAN', '=', 'kuesioner.IDKEGIATAN')
->leftJoin('hasilkuesioner', 'inptkegiatan.IDKEGIATAN', '=', 'hasilkuesioner.IDKEGIATAN')
->leftJoin('regiskegiatan', 'inptkegiatan.IDKEGIATAN', '=', 'regiskegiatan.IDKEGIATAN')
->where('inptkegiatan.IDNARASUMBER', '=', $value->PROFILEUSERS_ID)
->select([
'inptkegiatan.IDKEGIATAN',
\DB::raw('SELECT COUNT(kuesioner.PERTANYAAN)
FROM kuesioner
WHERE inptkegiatan.IDKEGIATAN = kuesioner.IDKEGIATAN) as totalPertanyaan'),
\DB::raw('(SELECT SUM(hasilkuesioner.JAWABAN)
FROM hasilkuesioner
WHERE kuesioner.IDKEGIATAN = hasilkuesioner.IDKEGIATAN) as totalJawaban'),
\DB::raw('(SELECT COUNT(regiskegiatan.IDKEGIATAN)
FROM regiskegiatan
WHERE hasilkuesioner.IDKEGIATAN = regiskegiatan.IDKEGIATAN ) as totalUser')
])
->groupBy('inptkegiatan.IDKEGIATAN')
->get();
Try with this. It should work
I'm trying to change the following query to laravel :
SELECT
*
FROM
usrusrs uu
,posts p
WHERE
(
uu.user_id = $u_id
or
uu.friend_id = $u_id
)
and
(
uu.user_id = p.user_id
OR
uu.friend_id = p.user_id
)
I tried the following, but it's giving different output. I think there might be something wrong with the joining between the two tables. any suggestions ?
$usrusrmembs = DB::table('usrusrs')
->join('posts', 'posts.user_id', '=', 'usrusrs.user_id')
->orwhere('posts.user_id', '=', 'usrusrs.friend_id')
->where('usrusrs.user_id', $u_id)
->orwhere('usrusrs.friend_id', $u_id)
->get();
Got it after some digging :
$usrusrmembs = DB::table('usrusrs')
->join('posts', function ($join) {
$join->on('posts.user_id', '=', 'usrusrs.user_id')->orOn('posts.user_id', '=', 'usrusrs.friend_id');
})
->where('usrusrs.user_id', $u_id)
->orwhere('usrusrs.friend_id', $u_id)
->get();
I use to PHP and Laravel Framework on my project.
Above code works perfectly
$users = User::select([
'users.id',
'users.name',
'users.company',
'users.country',
'users.city',
'users.email',
'users.created_at',
\DB::raw('SUM(reservations.dolar) as dolar'),
\DB::raw('count(reservations.confirmation) as confirmation'),
])->join('reservations','reservations.user_id','=','users.id')
->groupBy('reservations.user_id');
Now Counting all reservation.confirmation column but I want to count only reservation.confirmation column values 1
How I can edit
\DB::raw('count(reservations.confirmation) as confirmation'),
this code
Have you tried see in https://laravel.com/docs/5.6/queries#joins in the section "Advanced Join Clauses", you can add condition in Join function
$users = User::select([
'users.id',
'users.name',
'users.company',
'users.country',
'users.city',
'users.email',
'users.created_at',
\DB::raw('SUM(reservations.dolar) as dolar'),
\DB::raw('count(reservations.confirmation) as confirmation'),
])->join('reservations', function ($join) {
$join->on('reservations.user_id', '=', 'users.id')
->where('reservations.confirmation', '=', 1);
})->groupBy('reservations.user_id');
If you want have all sum dolar not depends with confirmation,
you can use 'case' statement:
\DB::raw('sum(case when reservations.confirmation=1 then 1 else 0 end) as confirmation')
or subquery:
\DB::raw('(Select count(*) FROM reservations WHERE user_id = users.id AND confirmation=1) as confirmation')
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();