execute multiple quires at once in laravel - php

I need to execute 3 quires when user comes to main page.
public function index()
{
$slider = \App\Slider::select("title", "poster", "link", "sub_title")->translate()->orderBy("created_at", "asc")->get();
$services = \App\Page::getPage(24)->tabs()->translate()->get();
$partners = \App\Partner::select('id', 'title', 'link')->translate()->get();
return view('Front/index', compact('slider', 'services', 'partners'));
}
as you can see, I need to get images from slider, take page data and take some company partners info. so i execute 3 quires to get what i want. is there way to make only one query and union all these 3 quires in one? I want something like multi_query function in php. no matter it would be in eloquent or query builder.
p.s. I don't eloquent relationships, these data aren't related to each other

just put ur query inside $qry=DB::select("your_query");
return view('your_view',compact('qry'));
you can see following also for better unterstand
$emp_id="5623";
$var_start_date=$request->startdate;
$data_query= DB::select("SELECT orinfo.*,
chinfo.name as chname
FROM order_info orinfo, ch_info chinfo
WHERE orinfo.ch_id= chinfo.ch_id
AND orinfo.emp_id= ?
AND
to_char(orinfo.order_Date,'mm/dd/yyyy') BETWEEN ? AND ? order by orinfo.order_Date desc",[$emp_id,$var_start_date,$var_end_date]);

Related

getting doubled queries laravel

I'm using laravel clockwork to monitor my queries
in my controller I have
public function index(){
$errorFound = false;
$error = ['error' => 'No Monitor Found'];
$urls = $this->url->with('url_status','latestUrlStatus','users');
if (request()->has('q')) {
$keyword = '%'.request()->get('q').'%';
$builder = $urls->where('description', 'like', $keyword);
$builder->count() ? $urls = $builder : $errorFound = true;
}
return $errorFound === false ? UrlsResource::collection($urls->latest()->paginate(5)->appends(request()->query())) : $error;
}
on my laravel clockwork im getting
doubled queries
is it normal? if it is a problem how can I fix this? TIA
There's no problem. All of those queries are expected.
The first query (select users...) isn't from the code you've shown. It came from TrustProxies.
The second query (select count()) is from $builder->count().
All the rest of the queries come from $urls->latest()->paginate(5). The first thing paginate() does is run a count() query (the third query) to get the total number of records. Then it moves on to call the real queries.
In this case, the fourth query is your main query for all your urls, the fifth query is the query to eager load your url_status relationship, the sixth query is the query to eager load your latestUrlStatus relationship, and the seventh query is the query to eager load your users relationship.

CodeIgniter - Count rows active record joint

I'm trying to better understand how CI works.
This is my first table, app_news:
id / name
My second is app_news_comments:
id / id_news / comment
The model I use in order to display news informations is:
public function get_news($where = array()) {
return $this->db->select('*')
->from('app_news')
->where($where)
->get()
->result();
}
The model I use in order to count comments for a news is:
public function count_comment($id_news) {
return (int) $this->db->where(array('id_news' => $id_news)
->count_all_results('app_news_comments');
}
The first solution I have is to print a foreach on my view and putting the count_comment function inside the loop in order to count how much comments I have however I won't respect the MVC pattern. How can I do so ?
The best way to get that information is using this query:
SELECT
app_news.id,
app_news.name,
COUNT(app_news_comments.id)
FROM app_news_comments
JOIN app_news ON app_news_comments.id_news = app_news.id
GROUP BY app_news_comments.id_news
So, you need to create a query using Active Record on Codeigniter or you could add the directly, because Active Record on Codeigniter have some restrictions.
However, you could use this way on Codeigniter to create the query:
$this->db->select('[YOUR FIELDS AND COUNT]', FALSE)
->from('app_news_comments') .... etc
and to add the query directly:
$this->db->query('[QUERY HERE]');
I hope this help you.

Eloquent HasMany relationship, with limited record count

I want to limit related records from
$categories = Category::with('exams')->get();
this will get me exams from all categories but what i would like is to get 5 exams from one category and for each category.
Category Model
public function Exams() {
return $this->hasMany('Exam');
}
Exam Model
public function category () {
return $this->belongsTo('Category');
}
I have tried couple of things but couldnt get it to work
First what i found is something like this
$categories = Category::with(['exams' => function($exams){
$exams->limit(5);
}])->get();
But the problem with this is it will only get me 5 records from all categories. Also i have tried to add limit to Category model
public function Exams() {
return $this->hasMany('Exam')->limit(5);
}
But this doesnt do anything and returns as tough it didnt have limit 5.
So is there a way i could do this with Eloquent or should i simply load everything (would like to pass on that) and use break with foreach?
There is no way to do this using Eloquent's eager loading. The options you have are:
Fetch categories with all examps and take only 5 exams for each of them:
$categories = Category::with('exams')->get()->map(function($category) {
$category->exams = $category->exams->take(5);
return $category;
});
It should be ok, as long as you do not have too much exam data in your database - "too much" will vary between projects, just best try and see if it's fast enough for you.
Fetch only categories and then fetch 5 exams for each of them with $category->exams. This will result in more queries being executed - one additional query per fetched category.
I just insert small logic inside it which is working for me.
$categories = Category::with('exams');
Step 1: I count the records which are coming in response
$totalRecordCount = $categories->count()
Step 2: Pass total count inside the with function
$categories->with([
'exams' => function($query) use($totalRecordCount){
$query->take(5*$totalRecordCount);
}
])
Step 3: Now you can retrieve the result as per requirement
$categories->get();

Can we merge doctrine querybuilders and retrieve each ones' results ? is that a best practice?

I have a website where I populate the first page with objects of different nature (last posts, last recipes, last ingredients published). I have currently one querybuilder and then one query for each of them because I call ->getQuery()->getResult() on each of them.
Is there not a way to merge all those querybuilders before executing the query so as to retrieve an array of results made of the results of each of those querybuilders ?
Would that be a best practice ? How would we do it ?
EDIT: what I hoped we could do:
$recipesQueryBuilder = $this->getDoctrine->getRepository('Recipe')->createQueryBuilder('r');
$postsQueryBuilder = $this->getDoctrine->getRepository('Post')->createQueryBuilder('p');
$results = mergeQueryBuilder($recipesQueryBuilder, $postQueryBuilder)->getQuery()->getResult();
$recipes = $results['r'];
$posts = $results['p'];
I do this with many of our queries. I doubt there is a formal "best practice" for this kind of thing, however I can vouch for the fact that re-using builders does simplify the code. For example:
public function getListBuilder(User $user)
{
return $this->createQueryBuilder('l')->where('l.user = :user')->setParameter('user', $user)->orderBy('l.name');
}
I have a number of queries that re-use this base builder. For example:
public function countLists(User $user = null)
{
$qb = $this->getListBuilder($user);
return $qb->select('COUNT(l)')->getQuery()->getSingleScalarResult();
}
Likewise another method findActiveLists() changes the order to createdAt and generates a query with setMaxResults() specified.

get count in relation table in yii2 Activerecord

I have two table for post and user. I want to show post count of user in users list gridview. In yii 1 I use this in model to define a relation for this purpose:
'postCount' => array(self::STAT, 'Post', 'author',
'condition' => 'status = ' . Post::ACTIVE),
...
User:find...().with('postCount').....
But i don't know how to implement this in Yii2 to get count of post in User:find():with('...') to show in gridview.
Anyone try this in yii2?
Here is an example of what I did and it seems to work fine so far. It was used to get a count of comments on a post. I simply used a standard active record count and created the relation with the where statement using $this->id and the primary key of the entry its getting a count for.
public function getComment_count()
{
return Comment::find()->where(['post' => $this->id])->count();
}
Just a passing it along...
You can try the code below:
User::find()->joinWith('posts',true,'RIGHT JOIN')->where(['user.id'=>'posts.id'])->count();
Or if you want to specify a user count:
//user id 2 for example
User::find()->joinWith('posts',true,'RIGHT JOIN')->where(['user.id'=>'posts.id','user.id'=>2])->count();
Please note that, posts is a relation defined in your User model like below:
public function getPosts()
{
return $this->hasMany(Post::className(), ['user_id' => 'id']);
}
Well still I think for those who it may concern, if you JUST want the count a select and not the data it will be better use this instead imho:
$count = (new \yii\db\Query())
->select('count(*)')
->from('table')
->where(['condition'=>'value'])
->scalar();
echo $count;

Categories