Join along with sum and order by in Eloquent - php

I'm trying to perform the following SQL query using Eloquent:
select s.username, s.link, s.followers, sum(h.count)
from users s, views h where h.username = s.username order by h.timestamp
I'm aware of the join(), sum() and select() methods, however, how can I perform the sum() and select() together?

To use a SUM() you will have to use DB::raw. Here is an example that should make your query work:
DB::table('users as s')
->select(DB::raw('s.username, s.link, s.followers, sum(h.count)'))
->join('views as h', 'h.username', '=', 's.username')
->orderBy('h.timestamp')
->get();

Related

laravel elequent builder join with paginate

i have this query to return data from two tables based on DISTINCT destination_tbls.destination
like the following:
SELECT DISTINCT
destination_tbls.destination,
MIN(sms_details.id),
MIN(sms_details.msg_timestamp) AS TIMESTAMP,
MIN(destination_tbls.count)
FROM
sms_details
JOIN
(
SELECT
*
FROM
destination_tbls
)
destination_tbls
ON destination_tbls.id = sms_details.destination_tbls_id
GROUP BY
destination_tbls.destination;
Now how to use the paginate with them,
I tried something like this but don't work:
DB::select('
SELECT DISTINCT destination_tbls.destination,MIN(sms_details.id),MIN(sms_details.msg_timestamp) AS TIMESTAMP,MIN(destination_tbls.count)
FROM sms_details
JOIN(SELECT * FROM destination_tbls) destination_tbls ON destination_tbls.id=sms_details.destination_tbls_id
GROUP BY destination_tbls.destination
')->simplePaginate(100);
Any help would be appreciated!
If you want to use laravel's pagination, you need to write the query using the query builder methods.
$results = DB::table('sms_details')
->select('destination_tbls.destination')
->selectRaw('min(sms_details.id)')
->selectRaw('min(sms_details.msg_timestamp) as timestamp')
->selectRaw('min(destination_tbls.count)')
->distinct()
->joinSub(
function ($sub) {
$sub->from('destination_tbls');
},
'destination_tbls',
function ($join) {
$join->on('destination_tbls.id', '=', 'sms_details.destination_tbls_id');
}
)
->groupBy('destination_tbls.destination')
->simplePaginate(100);
Since you're not really doing anything in the subquery join, you could join the table instead.
$query = DB::table('sms_details')
->select('destination_tbls.destination')
->selectRaw('min(sms_details.id)')
->selectRaw('min(sms_details.msg_timestamp) as timestamp')
->selectRaw('min(destination_tbls.count)')
->distinct()
->join('destination_tbls', 'destination_tbls.id', '=', 'sms_details.destination_tbls_id')
->groupBy('destination_tbls.destination')
->simplePaginate(100);

How to do self join in query builder no eloquent

Having hard time to do self join with query builder but getting unexpected results or query while using toSql() or get(), please don't suggest eloquent, just query builder with raw query.
Trying to get all child menus followed by their parent.
Id column also required
$users = DB::table('all_menus as A all_menus as B')
->select(DB::raw('A.menu_name__v1 As menu_name_parent, B.menu_name__v1 As menu_name_child'))
->where('A.id', '=' 'B.parent_menu_id__v1')
->toSql();
join() method supports to define an alias name, so you can self join with alias name like this query:
$users = DB::table('all_menus as A')
->join('all_menus as B', 'A.id', '=', 'B.parent_menu_id__v1')
->select('A.menu_name__v1 AS menu_name_parent', 'B.menu_name__v1 AS menu_name_child')
->toSql();

How to create SQL Join Statement in Laravel Controller

I have two table customer_id namely tbl_customer and tbl_stocks connected on the same database. My logic about this problem is JOIN sql statement.
This is for Laravel and MySQL, so far i've tried this on PHP and is working fine but when I implement it on laravel it is not working i wonder why?
here is my code in PHP and want to convert it to laravel but I dont know where to put? will i put it in the View or in the Controller
$query = "SELECT c.*, s.* FROM tbl_customer c JOIN tbl_stock s ON s.customer_id = c.customer_id AND c.customer_id = 1";
Controller
$data = DB::table('tbl_customer')
->join ...... //Im not sure about this
->select .... // neither this
->get();
print_r($data)
Model
I have no codes on my model
Routes
Route::get('/admin/shopcontrol', 'Admin\ShopsController#testquery');
I expect a result of fetching or getting the query or result of the values in just a simple echo and the fetch join is connected
Have you checked the Laravel site?
https://laravel.com/docs/5.7/queries#joins
It has a demonstration you could use to reorganize your code.
As it follows below from the site.
Joins
Inner Join Clause
The query builder may also be used to write join statements. To perform a basic "inner join", you may use the join method on a query builder instance. The first argument passed to the join method is the name of the table you need to join to, while the remaining arguments specify the column constraints for the join. Of course, as you can see, you can join to multiple tables in a single query:
$users = DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')
->get();
You may find more information there if it suits you.
Try this:
$data = DB::table('tbl_customer')
->join('tbl_stock', 'customer_id', '=', 'tbl_customer.customer_id')
->select('tbl_customer.*', 'tbl_stock.*')
->where('customer_id', '=', 1)
->get();

Laravel 5: Native SQL to Query Builder

I am trying to join 2 tables on Laravel 5 and have to use Query Builder. I have already got the sql for it but i am not able to convert it to Query Builder syntax. SQL is below
SELECT v.id, r.full_name, b.full_name, s.full_name
FROM vehicles v
LEFT JOIN clients r ON v.representive_client_id = r.id
LEFT JOIN clients b ON v.buyer_client_id = b.id
LEFT JOIN clients s ON v.seller_client_id = s.id
and what i tried is
$query_result = DB::table('vehicles')
->selectRaw($query)
->leftJoin('clients', 'vehicles.representive_client_id', '=', 'clients.id')
->leftJoin('clients', 'vehicles.buyer_client_id ', '=', 'clients.id')
->leftJoin('clients', 'vehicles.seller_client_id ', '=', 'clients.id')
->paginate(30);
The problem is i dont know how to use AS caluse for Query Builder as i need to retrive 3 different types of full_name columns from vehicles table.Anybody can help me about how to write it in a proper Query Builder syntax ?. Any help would be appreciated.
You can use aliases with select columns and tables as well as joins, because the Query Builder will know to quote them correctly. So you can do this without any problems:
$query_result = DB::table('vehicles v')
->select('v.id', 'r.full_name as r_name', 'b.full_name as b_name', 's.full_name as s_name')
->leftJoin('clients r', 'vehicles.representive_client_id', '=', 'r.id')
->leftJoin('clients b', 'vehicles.buyer_client_id ', '=', 'b.id')
->leftJoin('clients s', 'vehicles.seller_client_id ', '=', 's.id')
->paginate(30);
Of course, you can use whatever aliases you want for the selected columns. Actually one of the examples in the Query Builder Selects Documentation uses aliases: email as user_email.
To check the SQL query generated by the Query Builder you can use the toSql method. So in your case instead of ->paginate(30) you can have ->toSql(), which will return a string with the SQL generated by the Query Builder, which you can compare to your raw query and see if it matches.

Different results using same query with DB::raw and Eloquent

I'm getting some unexpected results when running an Eloquent join query. I get two different results from using the exact same query. One running with DB::raw(), the second with Eloquent.
In the Eloquent query, the Users that matches the
where squad_user.leave_time >= seasons.start_time
are missing and will not be included in the result set. The users that matches the
or squad_user.leave is null
will be included, however.
That's the only difference in the results from the two queries. The raw query actually produces the desired result set.
What really puzzles me is, if I check the query logs, both Laravel's and MySQL, I get the exact same query when running both the raw and Eloquent query.
Raw query (the actual query i get from the query log when running the Eloquent query)
return \DB::select(\DB::raw('
select users.*
from users
inner join squad_user on users.id = squad_user.user_id
inner join seasons on squad_user.squad_id = seasons.squad_id
where squad_user.join_time <= seasons.end_time
and (squad_user.leave_time >= seasons.start_time or squad_user.leave_time is null)
and seasons.id = :seasonId
'),
['seasonId' => 3]
);
Eloquent query
return User::join('squad_user', 'users.id', '=', 'squad_user.user_id')
->join('seasons', 'squad_user.squad_id', '=', 'seasons.squad_id')
->where('squad_user.join_time', '<=', 'seasons.end_time')
->where(function ($query)
{
$query->where('squad_user.leave_time', '>=', 'seasons.start_time')
->orWhereNull('squad_user.leave_time');
})
->where('seasons.id', 3)
->get(['users.*']);
Laravel's Eloquent query log
select `users`.*
from `users`
inner join `squad_user` on `users`.`id` = `squad_user`.`user_id`
inner join `seasons` on `squad_user`.`squad_id` = `seasons`.`squad_id`
where `squad_user`.`join_time` <= seasons.end_time
and (`squad_user`.`leave_time` >= seasons.start_time or `squad_user`.`leave_time` is null)
and `seasons`.`id` = 3
{"bindings":["seasons.end_time","seasons.start_time",3],"time":0.38,"name":"mysql"}
MySQL's general_log on the Eloquent query
select `users`.*
from `users`
inner join `squad_user` on `users`.`id` = `squad_user`.`user_id`
inner join `seasons` on `squad_user`.`squad_id` = `seasons`.`squad_id`
where `squad_user`.`join_time` <= ?
and (`squad_user`.`leave_time` >= ? or `squad_user`.`leave_time` is null)
and `seasons`.`id` = ?
MySQL's general_log on the Raw query
select users.*
from users
inner join squad_user on users.id = squad_user.user_id
inner join seasons on squad_user.squad_id = seasons.squad_id
where squad_user.join_time <= seasons.end_time
and (squad_user.leave_time >= seasons.start_time or squad_user.leave_time is null)
and seasons.id = ?
I would appreciate any pointers here, as I am very lost.
where binds 3rd param and treats it usually as a string, unless you tell it not to by using raw statement. DB::raw or whereRaw will work for you:
return User::join('squad_user', 'users.id', '=', 'squad_user.user_id')
->join('seasons', 'squad_user.squad_id', '=', 'seasons.squad_id')
->where('squad_user.join_time', '<=', DB::raw('seasons.end_time'))
->where(function ($query)
{
$query->where('squad_user.leave_time', '>=', DB::raw('seasons.start_time'))
->orWhereNull('squad_user.leave_time');
})
->where('seasons.id', 3)
->get(['users.*']);
Since Laravel Verion 5.2 you can also use whereColumn to verify that two columns are equal (or pass a comparison operator to the method):
->whereColumn('squad_user.join_time', '<=', 'seasons.end_time')

Categories