Laravel - Query Buider - SQL fields using LPAD statement - php

I'm cannot retry this query, in QueryBuilder:
select id, lpad(number, 12, 0), lpad(int, 2, 0) from users;
How I can, in the example not function...
DB::table('users') ->select('id', 'lpad(number, 12, 0)', 'lpad(int, 2, 0)' ->get();

You need to use selectRaw.
DB::table('users')
->selectRaw('id, lpad(number, 12, 0), lpad(int, 2, 0)')
->get();
https://laravel.com/docs/8.x/queries#selectraw

Related

How to query using whereBetween() from selected DB::raw() value

I have a query result with the selected DB raw result and I need to add another where between clause to that query with the selected DB raw result. my query is
$products = Product::leftJoin('product_reviews', 'product_reviews.product_id', '=', 'products.id')
->select(
'products.*',
DB::raw("IF(SUM(product_reviews.star_rating) != 0, SUM(product_reviews.star_rating) / COUNT(product_reviews.id), 0) AS rate")
)
->get();
I need to add ->whereBetween('rate', [4, 5]) like this to my query. How can I do that?
You must use ->havingBetween('rate', [4, 5])
$products = Product::leftJoin('product_reviews', 'product_reviews.product_id', '=', 'products.id')
->select(
'products.id',
DB::raw("IF(SUM(product_reviews.star_rating) != 0, SUM(product_reviews.star_rating) / COUNT(product_reviews.id), 0) AS rate")
)
->groupBy('products.id')
->havingBetween('rate', [4, 5])
->get();
Online Laravel query builder test
If whereBetween('rate', [4, 5]) doesn't work, I think you could do one of the following:
You could use a subquery
$sub = DB::query()
->select(
'products.*',
DB::raw("IF(SUM(product_reviews.star_rating) != 0, SUM(product_reviews.star_rating) / COUNT(product_reviews.id), 0) AS rate")
)
->from('products')
->leftJoin('product_reviews', 'product_reviews.product_id', '=', 'products.id');
$products = Product::query() // using Product:: instead of DB:: to cast every result to a model.
->fromSub($sub, 'products')
->whereBetween('rate', [4, 5]);
->get();
Filter after getting the results
$products = Product::query()
->select(
'products.*',
DB::raw("IF(SUM(product_reviews.star_rating) != 0, SUM(product_reviews.star_rating) / COUNT(product_reviews.id), 0) AS rate")
)
->leftJoin('product_reviews', 'product_reviews.product_id', '=', 'products.id')
->cursor()
->filter(fn($product) => $product->rate >= 4 && $product->rate <= 5)
->values()
->collect();
Or use DB::raw as the first argument of whereBetween
$products = Product::query()
->select(
'products.*',
DB::raw("IF(SUM(product_reviews.star_rating) != 0, SUM(product_reviews.star_rating) / COUNT(product_reviews.id), 0) AS rate")
)
->whereBetween(
DB::raw('IF(SUM(product_reviews.star_rating) != 0, SUM(product_reviews.star_rating) / COUNT(product_reviews.id), 0)'),
[4, 5]
)
->leftJoin('product_reviews', 'product_reviews.product_id', '=', 'products.id')
->get();
```

Laravel Eloquent JOIN() with primitive data type causes errors

I am new to Laravel. This query works perfectly:
$pageslugs = DB::table('page_slugs AS pslug')
->select(explode(',','pslug.page_id,pslug.slug,dslug.slug AS default_slug'))
->join('page_slugs AS dslug',function($join){
$join->on('dslug.page_id','=','pslug.page_id');
//$join->on('dslug.locale','=',DB::raw('en'));
//$join->on('dslug.locale','=','en');
$join->on('dslug.active','=',DB::raw(1));
})
->whereIn('pslug.page_id',Arr::pluck($menupages,'page_id'))
->where([['pslug.active','=',1],['pslug.locale','=',$lang],['dslug.locale','=',app('config')->get('app.locale')]])
->get()
->toArray();
But if I uncomment either of the $join->on('dslug.locale','=',DB::raw('en')); or $join->on('dslug.locale','=','en');, Then I get the error:
Illuminate\Database\QueryException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'en' in 'on clause' (SQL: select `pslug`.`page_id`, `pslug`.`slug`, `dslug`.`slug` as `default_slug` from `page_slugs` as `pslug` inner join `page_slugs` as `dslug` on `dslug`.`page_id` = `pslug`.`page_id` and `dslug`.`locale` = en and `dslug`.`active` = 1 where `pslug`.`page_id` in (19, 21, 11, 18, 22, 12, 13, 16, 14, 15, 17) and (`pslug`.`active` = 1 and `pslug`.`locale` = en and `dslug`.`locale` = en)) in file /var/www/john.project.com/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 664
How do you do a join against a primitive data type in Laravel?
I suppose you are trying to add extra filters to the join clause. This can be done by just adding where clauses to your join:
->join('page_slugs AS dslug', function ($join) {
$join->on('dslug.page_id', '=', 'pslug.page_id')
->where('dslug.locale', 'en')
->where('dslug.active', true);
})

MySQL/Eloquent force id by left join even if null

I have this query wrote in Eloquent :
return TypeModel::with(['apt' => function($q) use ($id){
$q->leftJoin('build_apt', function($join) use($id){
$join->on('build_apt.id_apt', '=', 'apt.id_apt');
$join->on('build_apt.id_build', '=', DB::raw($id->id_build));
})
}])
->get()
->toJson();
Equivalent SQL :
SELECT *
FROM `apt`
LEFT JOIN `build_apt`
ON `build_apt`.`id_apt` = `apt`.`id_apt`
AND `build_apt`.`id_build` = 1
WHERE `apt`.`id_typeapt` in (1, 2, 3, 4, 5)
I have the result I need except one thing, the id given is null :
[
{"id_typeapt":1,"apt":[
{"id_apt":null,"image_apt":"apt_1.png"},
{"id_aptitude":null,"image_apt":"apt_2.png"}
]
]
How can I force it to look for the id from the table "apt" and not giving me "null" as a result?
Thanks you!
EDIT : Where clause is coming from the with
public function apt(){
return $this->hasMany(AptModel::class, 'id_typeapt', 'id_typeapt');
}
EDIT2 :
id_apt was crushed by the other id_apt with a simple rename I could retrieve the id :
return TypeModel::with(['apt' => function($q) use ($id){
$q->leftJoin('build_apt', function($join) use($id){
$join->on('build_apt.id_apt', '=', 'apt.id_apt');
$join->on('build_apt.id_build', '=', DB::raw($id->id_build));
})
}])->select(DB::raw("*, apt.id_apt as id_apt);
}])
You are using LEFT JOIN, which is what you want, however you have conditions on the joined table in the WHERE clause. This actually turns your LEFT JOIN to an INNER JOIN, since unmatched records will be filtered out by the WHERE clause.
You would need to tweak your Eloquent code in order to generate the following SQL query :
SELECT *
FROM `apt`
LEFT JOIN `build_apt`
ON `build_apt`.`id_apt` = `apt`.`id_apt`
AND `build_apt`.`id_build` = 1
AND `apt`.`id_typeapt` in (1, 2, 3, 4, 5)

Laravel orderByRaw is removing results from union query

I am running this query in a project where I am having "meta_competitions" and "primary_events" that is going to merge together into a result where they do not overlap by primary_event_meta_competitions having the primary_event_id of the current primary_event.
Everything is working as expected in the query itself, we are getting the results we want. But when we add the orderByRaw() everything except one result is removed of the meta_competitions.
I have tried running the query I get when i am running "->toSql()" instead of ->get() of the query in pure sql and there everything works as expected.
$metaCompetitions = DB::table('meta_competitions')
->select('meta_competitions.name as name', 'sports.name as sport', 'meta_competitions.id', 'meta_competitions.country')
->where('meta_competitions.name', 'LIKE', "%{$string}%")
->whereIn('meta_competitions.sport_id', [1, 3, 4, 9])
->join('sports', 'sports.id', '=', 'meta_competitions.sport_id');
$leagues = DB::table('primary_events')
->select('primary_events.name as name', 'sports.name as sport', 'primary_events.id', 'primary_events.country')
->where('primary_events.name', 'LIKE', "%{$string}%")
->whereIn('primary_events.sport_id', [1, 3, 4, 9])
->whereNull('primary_event_meta_competitions.primary_event_id')
->leftJoin('primary_event_meta_competitions', 'primary_event_meta_competitions.primary_event_id', '=', 'primary_events.id')
->leftJoin('sports', 'sports.id', '=', 'primary_events.sport_id')
->union($metaCompetitions)
->orderByRaw(
'CASE
WHEN name = ? THEN 1
WHEN name LIKE ? THEN 2
WHEN name LIKE ? THEN 4
ELSE 3
END', [$string, "{$string}%", "%{$string}"]
)
->get();
dd($leagues);
The query that I get from ->toSql() and that works for me is the following:
(select `primary_events`.`name` as `name`, `sports`.`name` as `sport`, `primary_events`.`id`, `primary_events`.`country` from `primary_events`
left join `primary_event_meta_competitions` on `primary_event_meta_competitions`.`primary_event_id` = `primary_events`.`id`
left join `sports` on `sports`.`id` = `primary_events`.`sport_id`
where `primary_events`.`name` LIKE '%Allsvenskan%' and `primary_events`.`sport_id` in (1, 3, 4, 9) and `primary_event_meta_competitions`.`primary_event_id` is null)
union (select `meta_competitions`.`name` as `name`, `sports`.`name` as `sport`, `meta_competitions`.`id`, `meta_competitions`.`country` from `meta_competitions`
inner join `sports` on `sports`.`id` = `meta_competitions`.`sport_id`
where `meta_competitions`.`name` LIKE '%Allsvenskan%' and `meta_competitions`.`sport_id` in (1, 3, 4, 9))
order by CASE
WHEN name = 'Allsvenskan' THEN 1
WHEN name LIKE 'Allsvenskan%' THEN 2
WHEN name LIKE '%Allsvenskan' THEN 4
ELSE 3
END
My tables looks like:
meta_competitions
id:name:sport_id:country
primary_events
id:name:sport_id:country
sports
id:name
primary_event_meta_competitions
primary_event_id:meta_competition_id
This was kind of an odd issue. When I did not orderByRaw but used a selectRaw to a custom column and sorted that column everything worked as expected.
Why is this different at all?
$metaCompetitions = DB::table('meta_competitions')
->select('meta_competitions.name as name', 'sports.name as sport', 'meta_competitions.id', 'meta_competitions.country')
->selectRaw('CASE
WHEN meta_competitions.name = ? THEN 1
WHEN meta_competitions.name LIKE ? THEN 2
WHEN meta_competitions.name LIKE ? THEN 4
ELSE 3
END AS order_col', [$string, "$string%", "%$string"] )
->selectRaw("'meta_competition' AS type")
->where('meta_competitions.name', 'LIKE', "%{$string}%")
->whereIn('meta_competitions.sport_id', [1, 3, 4, 9])
->join('sports', 'sports.id', '=', 'meta_competitions.sport_id');
$leagues = DB::table('primary_events')
->select('primary_events.name as name', 'sports.name as sport', 'primary_events.id', 'primary_events.country')
->selectRaw('CASE
WHEN primary_events.name = ? THEN 1
WHEN primary_events.name LIKE ? THEN 2
WHEN primary_events.name LIKE ? THEN 4
ELSE 3
END AS order_col', [$string, "$string%", "%$string"] )
->selectRaw("'league' AS type")
->where('primary_events.name', 'LIKE', "%{$string}%")
->whereIn('primary_events.sport_id', [1, 3, 4, 9])
->whereNull('primary_event_meta_competitions.primary_event_id')
->leftJoin('primary_event_meta_competitions', 'primary_event_meta_competitions.primary_event_id', '=', 'primary_events.id')
->leftJoin('sports', 'sports.id', '=', 'primary_events.sport_id')
->union($metaCompetitions)
->orderBy('order_col')
->get();

How display result by random order, doctrine2 queryBuilder

I have entity Travel, let's say it has 30 entries for example :
1-
2-
3-
4-
.
.
.
30-
I'd like to select 6 entity randomly, for example : 2, 14, 7, 25, 16, 1
I have tried this code but it works, but the results are always displayed by order ASC (3,4,5,6,7,8,).
public function getRandomTravelsFrontend()
{
$count = $this->createQueryBuilder('t')
->select('COUNT(t)')
->getQuery()
->getSingleScalarResult();
$qb = $this->createQueryBuilder('t')
->leftJoin('t.image', 'i')
->addSelect('i')
->Where('t.enabled = 1')
->setMaxResults(6)
->setFirstResult(rand(0, $count - 6));
return $qb->getQuery()->getResult();
}
How to display result by random order ? and is it possible to select 6 entities like this : 2, 14, 7, 25, 16, 1 ?
You can use ORDER BY rand() in your SQL select statement.

Categories