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.
Related
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
I would like to know the rank based on my DB structure:
I have a model Post that belongs to a model called Edition (also one Edition has many Post).
One Post has many Like.
I would like to know the rank of a Post based on the Like count inside a particular Edition.
The code:
// Define the id of an edition
$edition_id = 53;
// The id of the post to retrieve rank
$post_id = 132;
// Compose the query by select all posts, of interested edition ...
$query = App\Models\Post::where('edition_id', $edition_id)
// ... with like count (this produce an additional field named likes_count) ...
->withCount('likes')
// ... in descendig order by this count.
->orderBy('likes_count', 'desc');
// By execute it I can get right results.
$query->get();
For people who are not familiar with Laravel Eloquent ORM, I report the sql query executed from code above:
select `posts`.*, (select count(*) from `likes` where `posts`.`id` = `likes`.`post_id` and `likes`.`deleted_at` is null) as `likes_count`
from `posts`
where `edition_id` = '53' and `posts`.`deleted_at` is null
order by `likes_count` desc
I report the query results:
=> Illuminate\Database\Eloquent\Collection {#994
all: [
App\Models\Post {#993
id: 135,
likes_count: 4,
},
App\Models\Post {#1075
id: 134,
likes_count: 3,
},
App\Models\Post {#1091
id: 133,
likes_count: 2,
},
App\Models\Post {#997
id: 132,
likes_count: 1,
},
App\Models\Post {#1038
id: 131,
likes_count: 0,
},
],
}
How can I get the row position of the record with a certain id from the results of the composed query?
For example, how to retrieve the rank result of the record with id = 132?
You can use a subquery:
$query = Post::where('edition_id', $edition_id)
->withCount('likes')
->selectRaw('#rank := #rank + 1 rank')
->from(DB::raw('`posts`, (SELECT #rank := 0) vars'))
->orderBy('likes_count', 'desc');
$posts = Post::fromSub($query, 'posts')->paginate();
$post = Post::fromSub($query, 'posts')->find($post_id);
Workaround for Laravel < 5.6:
Builder::macro('fromSub', function($query, $as) {
$this->bindings = array_merge(
array_slice($this->bindings, 0, 1),
['from' => $query->getBindings()],
array_slice($this->bindings, 1)
);
$sql = '('.$query->toSql().') as '.$this->grammar->wrap($as);
return $this->from(DB::raw($sql));
});
You can use the search() method to find the key:
The search method searches the collection for the given value and returns its key if found. If the item is not found, false is returned.
$id = 132;
$key = $query->search(function($post,$id) {
return $post->id === $id;
});
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();
$demos = Demo::whereIn('store_id', [1,2,4], function($query){
$query->where('status', 1);
})->paginate(10);
I know that this thats not working, But how can I work with this logic..?
[Select * from 'demos' where store_id in 1,2,4 and status = 1 ]
If I understand correctly you need something like this.
$demos = Demo::whereIn('store_id', [1, 2, 4])->where('status', 1)->paginate(10);
Chained "where" Eloquent methods == "AND" database query conditions.
Sometimes, it is better not use ORM`ish approach.
They say, old plain SQL is your best friend. So.
$data = \DB::select(
\DB::raw("SELECT * FROM `demos` WHERE `store_id` IN (:id1, :id2, :id3)"), array( ':id1' => 1, ':id2' => 2, ':id3' => 3 )
);
Or, if you have unknown count of store_id entries, you could:
$ids = array(1, 2, 3, 4, ...); // looks like unknown ammount of entries
$data = \DB::select(
\DB::raw("SELECT * FROM `demos` WHERE `store_id` IN (".rtrim(str_repeat('?,', count($ids)),',').")"), $ids
);
I understand that to do a select query is
$bearLawly = Bear::where('name', '=', 'Lawly')->first();
but how to I do a select query such as
SELECT * FROM bear where name = 'abc' AND age => '5' AND title = 'kid' ORDER BY name LIMIT 5, 10
Thanks!
You may try this:
$bearLawly = Bear::where('name', 'abc') // By default = will be used, so optional
->where('age', '>=', '5')
->where('title', 'kid')
->orderBy('name') // or orderBy('name', 'desc') for reverse
->take(5)->skip(10)->get();
According to following query:
SELECT * FROM bear where name = 'abc' AND age => '5' AND title = 'kid' ORDER BY name LIMIT 5, 10
Just chain them:
$bearLawly = Bear::where('name', 'Lawly')->where('age', '5')->first();