I have the query:
$estadolocacaoname = "naolocado";
$consulta = DB::select("SELECT locacao.estadolocacao, automovel.marca, automovel.modelo
FROM locacao
INNER JOIN automovel
ON locacao.id = automovel.id
where locacao.estadolocacao = ? ",[$estadolocacaoname]);
How make paginate of LARAVEL?
Laravel's pagination is a breeze when you use the query builder:
DB::table('locacao')
->join('automovel', 'locacao.id', '=', 'automovel.id')
->select('locacao.estadolocacao', 'automovel.marca', 'automovel.modelo')
->where('locacao.estadolocacao', '=', $estadolocacaoname)
->paginate(15);
Related
I have code from query builder I want to convert to eloquent but it doesn't work
my query builder code
$topkabupatens = DB::table('sekolahs as S')
->select('K.name', DB::raw('count(S.kabupaten) as jumlah_kabupaten'))
->join('kabupaten_kotas as K', 'S.kabupaten', '=', 'K.id')>orderBy('jumlah_kabupaten', 'DESC')->groupBy('K.name')->limit(10)->get();
my query builder code
$topkabupatens = Sekolah::with('kabupaten')->withCount('kabupaten')>orderBy('kabupaten_count', 'DESC')->groupBy('name')->limit(10)->get();
where is my mistake?
my query builder code runs but not with eloquent
try with
$topkabupatens = Sekolah::select('kabupaten_kotas.name')->withCount('kabupaten_kotas.kabupaten')
->leftjoin('kabupaten_kotas', 'Sekolah.kabupaten', '=', 'kabupaten_kotas.id')
->orderBy('kabupaten_count', 'DESC')
->groupBy('name')
->limit(10)
->get();
Can anyone help me out to convert this SQL to query builder!
SELECT topwords.*,
mw.word AS my_word
FROM topwords
LEFT JOIN (SELECT DISTINCT words.word
FROM definition_word
JOIN words
ON words.id = definition_word.word_id
WHERE definition_word.user_id = $user) AS mw
ON topwords.word = mw.word
I have a problem with how to use a subquery in leftjoin!
I tried something like this but it has error!
See error as image
DB::table('topwords')
->leftJoin(DB::raw("SELECT DISTINCT
words.word
FROM definition_word
JOIN words ON words.id = definition_word.word_id
WHERE definition_word.user_id = $user as mw"),"topwords.word", "=", "mw.word" )
->select(
"topwords.*",
"mw.word AS my_word"
)->orderBy('id','desc')->paginate(15);
you can use Join Sub query official document subquery-joins
$mw = DB::table('words')
->select('DISTINCT words.word')
->join('definition_word', function($join) use ($user)
{
$join->on('wordss.id', '=', 'definition_word.word_id')
->where('definition_word.user_id', $user);
});
$topwords = DB::table('topwords')
->joinSub($mw, 'mw',function ($join) {
$join->on('topwords.word', '=', 'mw.word');
})
->select('topwords.*','mw.word AS my_word')
->orderBy('id','desc')
->paginate(15);
You have this error because of paginate and aggregation
Try to make custom pagination, using LengthAwarePaginator
Here is example: Laracast
So you need to make something like this:
$query = DB::table('topwords')
->leftJoin(DB::raw("SELECT DISTINCT
words.word
FROM definition_word
JOIN words ON words.id = definition_word.word_id
WHERE definition_word.user_id = $user as mw"),"topwords.word", "=", "mw.word" )
->select(
"topwords.*",
"mw.word AS my_word"
);
$paginator = new LengthAwarePaginator($query->get(), $query->count(), $request->input('per_page', 15), $request->input('page', 1));
And then you can use it in the collection
I have sql query that is working fine in MySQL. I want to get profile id from profiles table using join with user table.
SELECT profiles.profile_id FROM profiles
left JOIN users on profiles.id = users.id where users.id = 1
Laravel Query builder query is
$my_user_id = Auth::user()->id;
$my_id = DB::table('profiles')->select('profiles.profile_id')
->leftjoin('users','users.id' ,'=' ,'profiles.id')
->pluck('profiles.profile_id')
->where('users.id',$my_user_id)
->first();
Call where() before pluck() (select() is not necessary):
$my_id = DB::table('profiles')
->leftJoin('users', 'users.id', '=' , 'profiles.id')
->where('users.id', $my_user_id)
->pluck('profiles.profile_id')
->first();
You can also shorten it with value():
$my_id = DB::table('profiles')
->leftJoin('users', 'users.id', '=' , 'profiles.id')
->where('users.id', $my_user_id)
->value('profiles.profile_id');
You should select the id as well to perform the join :
DB::table('profiles')->select('profiles.profile_id', 'profiles.id')
->leftjoin('users','users.id' ,'=' ,'profiles.id')
->where('users.id',$my_user_id)
->pluck('profiles.profile_id')
->first();
It seems Laravel pagination does not working properly with group by clause. For example:
$users = Subject::select(DB::raw('subjects.*, count(user_subjects.id) as total_users'))
->join('user_subjects', 'user_subjects.subject_id', '=', 'subjects.id')
->whereNull('user_subjects.deleted_at')
->groupBy('subjects.id')
->orderBy('subjects.updated_at', 'desc')
->paginate(25);
Produced
select subjects.*, count(user_subjects.id) as total_users
from `subjects` inner join `user_subjects` on `user_subjects`.`subject_id` = `subjects`.`id`
where `subjects`.`deleted_at` is null and `user_subjects`.`deleted_at` is null
group by `subjects`.`id`
order by `subjects`.`updated_at` desc
note that, there is no limit clause on the query.
Working fine if no group by clause in the query:
$users = Subject::select(DB::raw('subjects.*, count(user_subjects.id) as total_users'))
->join('user_subjects', 'user_subjects.subject_id', '=', 'subjects.id')
->whereNull('user_subjects.deleted_at')
->orderBy('subjects.updated_at', 'desc')
->paginate(25);
produced the following query:
select subjects.*, count(user_subjects.id) as total_users from `subjects`
inner join `user_subjects` on `user_subjects`.`subject_id` = `subjects`.`id`
where `subjects`.`deleted_at` is null and `user_subjects`.`deleted_at` is null
order by `subjects`.`updated_at` desc
limit 25 offset 0
does anyone has any idea how can i fix this?
Check the documentation
https://laravel.com/docs/5.2/pagination
Currently, pagination operations that use a groupBy statement cannot
be executed efficiently by Laravel. If you need to use a groupBy with
a paginated result set, it is recommended that you query the database
and create a paginator manually.
I know it is an old question, by I am sharing my solution for future reference.
I managed to write a function based on this link which does the heavy job of determining the pagination of a complex query. Just pass the 'QueryBuilder' and it will return the paginated object/collection.
Additionally, this procedure can track and maintain the other parameters except for page=.
public function mergeQueryPaginate(\Illuminate\Database\Eloquent\Builder $query): \Illuminate\Pagination\LengthAwarePaginator
{
$raw_query = $query;
$totalCount = $raw_query->get()->count();
$perPage = request('per-page', 10);
$page = request('page', 1);
$skip = $perPage * ($page - 1);
$raw_query = $raw_query->take($perPage)->skip($skip);
$parameters = request()->getQueryString();
$parameters = preg_replace('/&page(=[^&]*)?|^page(=[^&]*)?&?/', '', $parameters);
$path = url(request()->getPathInfo() . '?' . $parameters);
$rows = $raw_query->get();
$paginator = new LengthAwarePaginator($rows, $totalCount, $perPage, $page);
$paginator = $paginator->withPath($path);
return $paginator;
}
This works for me in laravel 5.2
Select(\DB::RAW("assignment_descendant_child.assignment_descendant_child_id, assignment_descendant_child.assignment_descendant_child_name, COUNT(assignment_descendant.assignment_descendant_id) as xNum"))
->leftJoin(
'assignment_descendant',
'assignment_descendant.assignment_descendant_child_id',
'=',
'assignment_descendant_child.assignment_descendant_child_id'
)
->orderBy('assignment_descendant_child_name')
->groupBy('assignment_descendant_child.assignment_descendant_child_id')
->paginate(\Config::get('constants.paginate_org_index'))
create a database view namedvw_anything. MySql query will be like
create view vw_anything as select subjects.*, count(user_subjects.id) as total_users from subjects inner join user_subjects on user_subjects.subject_id = subjects.id
where subjects.deleted_at is null and user_subjects.deleted_at is null group by subjects.id;
Now create a new model named UserSubModel for this view, protected $table = 'vw_anything';
Now your paginate query will be like UserSubModel::orderBy('subjects.updated_at', 'desc')->paginate(25);
.
To answer this questioin Laravel Pagination group by year and month only
View query will be :
create view vw_anything as select gallery.*, DATE_FORMAT(created_at, "%Y-%m") as tanggal,count(created_at) as jumlah from gallery group by tanggal;
Let you model is VwModel then your paginate query will be
VwModel::where('type','Foto')->orderBy('tanggal','desc')->paginate(2);
This works if you want to group by and paginate.
$code = DB::table('sources')
->select(DB::raw('sources.id_code,sources.title,avg(point) point'))
->join('rating','sources.id_code','rating.id_code')
->groupBy('sources.id_code')
->groupBy('sources.title')
->groupBy('sources.language')
->groupBy('sources.visited')
->paginate(5);
I'm trying to add a condition using a JOIN query with Laravel Query Builder.
<?php
$results = DB::select('
SELECT DISTINCT
*
FROM
rooms
LEFT JOIN bookings
ON rooms.id = bookings.room_type_id
AND ( bookings.arrival between ? and ?
OR bookings.departure between ? and ? )
WHERE
bookings.room_type_id IS NULL
LIMIT 20',
array('2012-05-01', '2012-05-10', '2012-05-01', '2012-05-10')
);
I know I can use Raw Expressions but then there will be SQL injection points. I've tried the following with Query Builder but the generated query (and obviously, query results) aren't what I intended:
$results = DB::table('rooms')
->distinct()
->leftJoin('bookings', function ($join) {
$join->on('rooms.id', '=', 'bookings.room_type_id');
})
->whereBetween('arrival', array('2012-05-01', '2012-05-10'))
->whereBetween('departure', array('2012-05-01', '2012-05-10'))
->where('bookings.room_type_id', '=', null)
->get();
This is the generated query by Laravel:
select distinct * from `room_type_info`
left join `bookings`
on `room_type_info`.`id` = `bookings`.`room_type_id`
where `arrival` between ? and ?
and `departure` between ? and ?
and `bookings`.`room_type_id` is null
As you can see, the query output doesn't have the structure (especially under JOIN scope). Is it possible to add additional conditions under the JOIN?
How can I build the same query using Laravel's Query Builder (if possible) Is it better to use Eloquent, or should stay with DB::select?
$results = DB::table('rooms')
->distinct()
->leftJoin('bookings', function($join)
{
$join->on('rooms.id', '=', 'bookings.room_type_id');
$join->on('arrival','>=',DB::raw("'2012-05-01'"));
$join->on('arrival','<=',DB::raw("'2012-05-10'"));
$join->on('departure','>=',DB::raw("'2012-05-01'"));
$join->on('departure','<=',DB::raw("'2012-05-10'"));
})
->where('bookings.room_type_id', '=', NULL)
->get();
Not quite sure if the between clause can be added to the join in laravel.
Notes:
DB::raw() instructs Laravel not to put back quotes.
By passing a closure to join methods you can add more join conditions to it, on() will add AND condition and orOn() will add OR condition.
If you have some params, you can do this.
$results = DB::table('rooms')
->distinct()
->leftJoin('bookings', function($join) use ($param1, $param2)
{
$join->on('rooms.id', '=', 'bookings.room_type_id');
$join->on('arrival','=',DB::raw("'".$param1."'"));
$join->on('arrival','=',DB::raw("'".$param2."'"));
})
->where('bookings.room_type_id', '=', NULL)
->get();
and then return your query
return $results;
You can replicate those brackets in the left join:
LEFT JOIN bookings
ON rooms.id = bookings.room_type_id
AND ( bookings.arrival between ? and ?
OR bookings.departure between ? and ? )
is
->leftJoin('bookings', function($join){
$join->on('rooms.id', '=', 'bookings.room_type_id');
$join->on(DB::raw('( bookings.arrival between ? and ? OR bookings.departure between ? and ? )'), DB::raw(''), DB::raw(''));
})
You'll then have to set the bindings later using "setBindings" as described in this SO post:
How to bind parameters to a raw DB query in Laravel that's used on a model?
It's not pretty but it works.
The sql query sample like this
LEFT JOIN bookings
ON rooms.id = bookings.room_type_id
AND (bookings.arrival = ?
OR bookings.departure = ?)
Laravel join with multiple conditions
->leftJoin('bookings', function($join) use ($param1, $param2) {
$join->on('rooms.id', '=', 'bookings.room_type_id');
$join->on(function($query) use ($param1, $param2) {
$query->on('bookings.arrival', '=', $param1);
$query->orOn('departure', '=',$param2);
});
})
I am using laravel5.2 and we can add joins with different options, you can modify as per your requirement.
Option 1:
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')->orOn(...);//you add more joins here
})// and you add more joins here
->get();
Option 2:
$users = DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')// you may add more joins
->select('users.*', 'contacts.phone', 'orders.price')
->get();
option 3:
$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->leftJoin('...', '...', '...', '...')// you may add more joins
->get();
For conditional params we can use where,
$results = DB::table('rooms')
->distinct()
->leftJoin('bookings', function($join) use ($param)
{
$join->on('rooms.id', '=', 'bookings.room_type_id')
->where('arrival','=', $param);
})
->where('bookings.room_type_id', '=', NULL)
->get();
There's a difference between the raw queries and standard selects (between the DB::raw and DB::select methods).
You can do what you want using a DB::select and simply dropping in the ? placeholder much like you do with prepared statements (it's actually what it's doing).
A small example:
$results = DB::select('SELECT * FROM user WHERE username=?', ['jason']);
The second parameter is an array of values that will be used to replace the placeholders in the query from left to right.
My five cents for scheme LEFT JOIN ON (.. or ..) and (.. or ..) and ..
->join('checks','checks.id','check_id')
->leftJoin('schema_risks', function (JoinClause $join) use($order_type_id, $check_group_id, $filial_id){
$join->on(function($join){
$join->on('schema_risks.check_method_id','=', 'check_id')
->orWhereNull('schema_risks.check_method_id')
;
})
->on(function($join) use ($order_type_id) {
$join->where('schema_risks.order_type_id', $order_type_id)
->orWhereNull('schema_risks.order_type_id')
;
})
->on(function($join) use ($check_group_id) {
$join->where('schema_risks.check_group_id', $check_group_id)
->orWhereNull('schema_risks.check_group_id')
;
})
->on(function($join) use($filial_id){
$join->whereNull('schema_risks.filial_id');
if ($filial_id){
$join->orWhere('schema_risks.filial_id', $filial_id);
}
})
->on(function($join){
$join->whereNull('schema_risks.check_risk_level_id')
->orWhere('schema_risks.check_risk_level_id', '>' , CheckRiskLevel::CRL_NORMALLLY );
})
;
})