Base on this question finally can show result of query in phppgAdmin faster then before. Only add LIMIT 1 after PostgreSQL CONCAT function make different about 5s which is from 7s to 2s.
This is my short sql:
$sql = "select tb1.*,
(select name_code from master_code tb2 where tb2.code like CONCAT('%', tb1.code, '%') LIMIT 1) as master_code_name
from city tb1 where tb1.location_id like 'blablabla%'";
I use this script to show city based on location_id. One column of city contain code from master_code. Actually, I just want to try to show the name of that column. But when I try to load using Model and Controller, showing 500 Internal Server Error in console.
This is code in Model:
public function select_by_location(){
$sql = "select tb1.*, (select name_code from master_code tb2 where tb2.code like CONCAT('%', tb1.code, '%') LIMIT 1) as master_code_name from city tb1 where tb1.location_id like 'blablabla%'";
$data = $this->db->query($sql);
return $data->result_array();
}
This is the Controller:
public function show() {
$data['dataCity'] = $this->M_city->select_by_location();
$this->load->view('city/list_data', $data);
}
Ajax:
function showCityAjax() {
$.get('<?php echo base_url('City_controller/show'); ?>', function(data) {
$('#data-city').html(data);
refresh();
});
}
Show result in:
<div id="data-city"></div>
How to resolve this? Or is there another way to do it more efficiently. Thanks.
Related
Using laravel 7 and pivot tables i have something like this:
Model: show
public function genres()
{
return $this->belongsToMany('App\ShowGenre');
}
Model: ShowGenre
public function shows()
{
return $this->belongsToMany('App\Show', 'show_show_genre')->orderBy('name', 'asc');
}
In mysql database i have show_genres where i put my show_id and genre_id. So i want to create something like suggestion based.
At bottom my page i want to display 5 random tv shows that have same genre. Some tv shows have multiple genres so how can i display that and limit it with suma 5.
show_show_genre should have show_id and show_genre_id because show_show_genre is pivot table. show_genres is not pivot table since it is genre's table as described in code. Also, you don't need to set show_show_genre in return statement since Laravel will automatically recognize it's pivot table.
Try something like this:
$show = Show::findOrFail($id);
$featuredShows = Show::whereHas('genres', function ($query) use ($show) {
$query->whereIn('show_genres.id', $show->genres()->pluck('id')->toArray());
})->where('id', '!=' , $show->id)->with(['genres'])->inRandomOrder()->limit(5)->get();
I'm using Laravel pagination (https://laravel.com/docs/6.x/pagination#paginating-eloquent-results)
like this:
// the Controller contains
$users = App\User::paginate(15);
Running this code, I noticed that are executed two queries:
To get the number of total items: select count(*) as aggregate from user
To get the first 15 items: select * from user limit 15 offset 0
I'd like to cache this queries, and the question is: from App\User::paginate(15) is there a way to get the sql(s) that will be executed? select count(*) as aggregate from user and select * from user limit 15 offset 0?
The code App\User::paginate(15) return a LengthAwarePaginator class; can I get the sql executed from this class?
The idea is to create my own method to cache this pagination request. Something like:
// the Model contains
public static function paginateWithQueryCache($itemPerPage) {
$query = self::query();
$cacheKeyString = $query->toSql();
$cacheKeyStringMD5 = md5($cacheKeyString);
return \Cache::remember($cacheKeyStringMD5, 60, function() use ($itemPerPage) {
return self::paginate($itemPerPage);
});
}
// the Controller will be update with
$users = App\User:: paginateWithQueryCache(15);
The problem here is that the $query->toSql() used as a cache key, is a simple query to the model (select * from user) instead of a pagination query (select * from user limit 15 offset 0); this is a problem switching to second page, page=2.
Thank you.
The query select count(*) as aggregate from user (that is very slow in my case with millions of records in a database table) is executed from Illuminate\Database\Query::getCountForPagination(), then to cache it I need to extend the class and implement the cache.
I changed the approach and I decided to cache all pagination output:
// Controller
public function paginateCache($model, $cacheExpireInSeconds = 120)
{
$cacheKeyString = request()->fullUrl();
$cacheKeyStringMD5 = md5($cacheKeyString);
/* Closure to get data */
$func_get_data = function() use ($model) {
return $model::paginate(1000);
};
/* Caching */
return \Cache::remember($cacheKeyStringMD5, $cacheExpireInSeconds, $func_get_data);
}
public function index()
{
return $this->paginateCache(User::class);
}
I can't wrap my head around this for some reason even though it seems the answer is right in front of me.
I have 3 tables, rentals, amenitiesand amenities_rentals
Amenities are things like air conditioning, staff ect.
The amenities_rentals has rentail_id, amenities_id. This table is basically a reference table that connects rentals to amenities.
In a search a user can narrow down rentals by checking off certain amenities. As of now its giving me all the rentals that have at leas one of the checked off options. I need it to narrow down to only rentals that have ALL of the chosen amenities. This is what I have, this is not only not pulling the info correct but I know there is a better way to do it.
if($request->has('amenities'))
{
$rental_ids = AmenitiesRentals::select('rental_id')
->whereIn('amenities_id',$request->amenities)
->distinct()
->get();
$builder->whereIn('rentals.id', $rental_ids->toArray());
}
The rest of the builder works fine.
As Kamal Paliwal suggested, define a BelongsToMany relationship in your Rental model:
public function amenities() {
return $this->belongsToMany(Amenity::class, 'amenities_rentals', 'rental_id', 'amenities_id');
}
Then use whereHas():
$amenities = $request->amenities;
$rentals = Rental::whereHas('amenities', function ($query) use ($amenities) {
$query->whereIn('amenities.id', $amenities);
}, '=', count($amenities))->get();
You should create a many relationship between rentals and amenities like below:
public function amenities()
{
return $this->belongsToMany(\AmenityModel::class, 'amenities_rentals', 'rental_id', 'amenities_id');
}
Then while applying filter you can add it in this way:
$amenitiesIds = $request->amenities;
RentalsModel::with('amenities')->whereHas('amenities', function ($q) use ($amenitiesIds) {
$q->whereIn('amenities_id', $amenitiesIds);
})
Hope this might help you.
You should select rentals that has the count of amenities ids same as the size of amenities array from your request by grouping rentals by amenities count.
Here is an example:
$amenities_ids = $request->amenities;
$amenities_ids_count = count($amenities_ids);
$rental_ids = AmenitiesRentals::selectRaw("COUNT(amenities_id) as amenities_count, rentail_id")
->whereIn('amenities_id', $amenities_ids)
->groupBy('rentail_id')
->having('amenities_count', $amenities_ids_count)
->get();
I have 3 tables as follow
dealer
id - dealer_name
specialties
id - name
dealer_specialty
id - dealer_id - specialty_id
So Dealer and Speciality model have many to many relation ship so in their models they looks like
Dealer.php
public function specialties()
{
return $this->belongsToMany('App\Models\Specialty');
}
In Speciality.php
public function dealers()
{
return $this->belongsToMany('App\Models\Dealer');
}
Now I have a scenario, where user can filter the result. Like at first whole dealers table will be shown. Now user can filter result with specialties and dealer name. So I have made route with optional parameters. And on my controller I am checking if param ins't empty put a where condition. Its working only with dealer_name as its where condition is referring to its own table. I got problem when I need to put where condition with specialty table.
My code looks like
$dealerArray = DB::table('dealers');
if(!empty($speciality )) {
// how to put where condition like get all dealers with specialit id 4, if this condition matches. I have tried following but its definitely generating error.
$dealerArray->specialities()->where('blah blah blah');
//I have also tried whereHas..
}
if(!empty($keyword)) {
$dealerArray->where('dealer_name','Like','%'.$keyword.'%');
}
return $dealerArray->get() ;
So finally I want to know how can I put an option condition that If I have to filter dealers from specialty id, how can I do that.
Try this one
In the Dealer.php
public function specialties()
{
return $this->belongsToMany(Speciality::class, 'dealer_specialty', 'dealer_id', 'specialty_id');
}
In Speciality.php
public function dealers()
{
return $this->belongsToMany(Dealer::class, 'dealer_specialty', 'specialty_id', 'dealer_id');
}
Query
$dealerArray = new Dealer();
if (!empty($speciality)) {
// how to put where condition like get all dealers with speciality id 4,
// if this condition matches. I have tried following but its definitely generating error.
$dealerArray = $dealerArray->whereHas('specialties', function ($query) use ($speciality) {
$query->where('specialty_id', $speciality);
});
//I have also tried whereHas..
}
if (!empty($keyword)) {
$dealerArray = $dealerArray->where('dealer_name', 'Like', '%' . $keyword . '%');
}
return $dealerArray->get();
I have three tables that are as follows:
invent_accessory
id,code,detail,is_length
invent_price_accessory
id,invent_accessory_id_fk,price,color
invent_price_accessory_length
id,invent_accessory_id_fk,price,color
how do i combine these three tables so that i can get id,code,detal,is_length,price,color
i have done following but it doesnt not return any data:
public function getAccessoryInventPrice(){
$accessory=DB::table('invent_accessory')
->select('invent_accessory.id as accessory_id')
->join('invent_price_accessory','invent_price_accessory.invent_accessory_id_fk','=','invent_accessory.id')
->join('invent_price_accessory_length','invent_price_accessory_length.invent_accessory_id_fk','=','invent_accessory.id')
->get();
return $accessory;
}
I am guessing that I have to do Union between invent_price_accessory and invent_price_accessory_length first then join with invent_accessory? How do i do this? pls help.
My guess was right!! i was able to solve this by:
public function getAccessoryInventPrice(){
$data1=\DB::table('invent_price_accessory')->select('accessory_code_id','color_id','rate');
$data2=\DB::table('invent_price_acc_length')->select('accessory_code_id','color_id','rate')
->union($data1);
$query= \DB::table(\DB::raw("({$data2->toSql()}) as invent_price"))
->join('invent_accessory','invent_price.accessory_code_id','=','invent_accessory.id')
->join('invent_color','invent_price.color_id','=','invent_color.id')
->select('invent_accessory.id','code','sl_detail','is_length','rate','invent_color.name')
->orderBy('invent_accessory.id','asc')
->get();
return $query;
}