Memory size error in laravel pagination - laravel

When I try to select some field with join query with pagination it show en error like
Allowed memory size of 134217728 bytes exhausted (tried to allocate 45797376 bytes)
My query is
$price_all = DB::table('model_price')
->join('operator_model','model_price.model_id','=','operator_model.id')
->join('operator_route','operator_model.operator_route_id','=','operator_route.id')
->join('route', 'operator_route.route_id', '=', 'route.id')
->join('operator', 'operator_route.operator_id', '=', 'operator.id')
->select('model_price.id', 'model_price.price', 'route.route_name', 'operator.operator_name')
->paginate(2);
In my database only 5 records are stored. it not big data.
when I try without pagination then it works fine. like
$price_all = DB::table('model_price')
->join('operator_model','model_price.model_id','=','operator_model.id')
->join('operator_route','operator_model.operator_route_id','=','operator_route.id')
->join('route', 'operator_route.route_id', '=', 'route.id')
->join('operator', 'operator_route.operator_id', '=', 'operator.id')
->select('model_price.id', 'model_price.price', 'route.route_name', 'operator.operator_name')
->get();
Now how can I optimize this query.

Try using Offset & Limit instead of paginate.
$price_all = DB::table('model_price')
->join('operator_model','model_price.model_id','=','operator_model.id')
->join('operator_route','operator_model.operator_route_id','=','operator_route.id')
->join('route', 'operator_route.route_id', '=', 'route.id')
->join('operator', 'operator_route.operator_id', '=', 'operator.id')
->select('model_price.id', 'model_price.price', 'route.route_name', 'operator.operator_name')
->skip(0)
->take(2)
->get();

Related

How to write raw query in Laravel?

There is a query:
SELECT ST_DistanceSpheroid(geometry(location), ST_GeomFromText('POINT(37.854289 55.685333)'), 'SPHEROID["WGS 84",6378137,298.257223563]')
FROM users
How to pass parameter 37.854289 55.685333?
Also I tried this:
$point = "37.854289 55.685333";
return DB::table('users')
->select(DB::raw('ST_DistanceSpheroid(geometry(location), ST_GeomFromText(\'POINT(?)\'), \'SPHEROID["WGS 84",6378137,298.257223563]\''), [$point])
->get();
I got this error:
"message": "stripos(): Argument #1 ($haystack) must be of type string, array given",
My attempt bases accepted question:
$lon = 37.857397;
$lat = 55.685333;
return DB::table('users')
->selectRaw(
"(ST_DistanceSpheroid(
geometry(location),
ST_GeomFromText('POINT(? ?)'),
'SPHEROID[?, ?, ?]'
)) as distance",
[$lon, $lat, 'WGS 84', 6378137, 298.257223563]
)->leftJoin('doctors', 'doctors.user_id', 'users.id')->orderBy('distance', 'ASC')->get();
I have got an error:
{
"message": "PDO: SQLSTATE[XX000]: Internal error: 7 ОШИБКА: SPHEROID parser - couldnt parse the spheroid\nLINE 4: 'SPHEROID[?, ?, ?]'\n ^ (SQL: select (ST_DistanceSpheroid(\n geometry(location),\n ST_GeomFromText('POINT(37.857397 55.685333)'),\n 'SPHEROID[WGS 84, 6378137, 298.257223563]'\n )) as distance from \"users\" left join \"doctors\" on \"doctors\".\"user_id\" = \"users\".\"id\" order by \"distance\" asc)"
}
The row query that works:
SELECT doctors.user_id, (ST_DistanceSpheroid(geometry(location), ST_GeomFromText('POINT(37.857397 55.690576)'), 'SPHEROID["WGS 84",6378137,298.257223563]')
) as distance FROM users INNER JOIN doctors ON doctors.user_id = users.id ORDER BY distance ASC
You almost got it. The [$point] parameter should be the second parameter of DB::raw($query, $bindings) but you added it as a second parameter to select().
// What you have
->select(DB::raw(...), [$point])
// correct syntax
->select(DB::raw(..., [$point]))
If you've got nothing else to put in your select clause, might as well use selectRaw(). It's the same as select(DB::raw()).
DB::table('users')
->selectRaw('ST_DistanceSpheroid(geometry(location), ST_GeomFromText(\'POINT(?)\'), \'SPHEROID["WGS 84",6378137,298.257223563]\')', [$point])
Personally, I'd write the query like this:
$query = DB::table('users')
->selectRaw(
"ST_DistanceSpheroid(
geometry(location),
ST_GeomFromText('POINT(? ?)'),
'SPHEROID[?, ?, ?]'
)",
[37.854289, 55.685333, 'WGS 84', 6378137, 298.257223563]
)
->get();

difference between 2 dates - illuminate manager laravel

I make a tv program schedule and I need to sort dates that are more than 600 seconds apart
But it don't work ;(
Anyone know how to do it?
Many thanks in advance to those who will help me.
$dateMin = Carbon::now('Europe/Paris')
->endOfDay()
->addDay()
->addHours(-4)
->timestamp;
$dateMax = Carbon::now('Europe/Paris')
->endOfDay()
->addDay()
->timestamp;
$datas = Capsule::table('channels')
->select('channels.number',
'channels.slug',
'channels.display-name',
'channels.icon',
'programs.start',
'programs.stop',
'programs.title',
'programs.img',
'programs.thumbnail',
'programs.desc'
)
->where([
['start', '>', $dateMin],
['stop', '>', $dateMin],
['start', '<', $dateMax],
])
->whereRaw('stop - start > 601')
->leftJoin('programs', 'channels.slug', '=', 'programs.slug')
->orderBy('number')
->orderBy('start')
->get();
return $datas->groupBy('display-name');
Without much context, the only thing I can think of is to try grouping the parameters in where clause
$datas = Capsule::table('channels')
->select('channels.number',
'channels.slug',
'channels.display-name',
'channels.icon',
'programs.start',
'programs.stop',
'programs.title',
'programs.img',
'programs.thumbnail',
'programs.desc'
)
->where(function($query) use($dateMin,$dateMax) {
$query->where([
['start', '>', $dateMin],
['stop', '>', $dateMin],
['start', '<', $dateMax],
])
->whereRaw('stop - start > 601')
})
->leftJoin('programs', 'channels.slug', '=', 'programs.slug')
->orderBy('number')
->orderBy('start')
->get();
If this doesn't work, try dumping the query sql for both, without parameter grouping (code in your question) and with parameter grouping (code above in my answer) and see the sql statement generated. You can get the query sql using toSql() in place of get().

How to Only fetch time from timestamp in laravel

I am working on a Laravel project. I am trying to fetch time from a timestamp. This is the code I'm using to try to accomplish this:
$details=DB::table('CourseListNew as cl')
->select(
'cl.Title',
'p.Title as ParentTitle',
'cd.Trainer',
DB::raw('day(cd.StartingDate) as day'),
DB::raw('day(cd.EndingDate) as day_end'),
DB::raw('(cd.StartingDate) as month'),
DB::raw('year(cd.StartingDate) as year'),
DB::raw('time(cd.StartingDate) as start_time'),
DB::raw('time(cd.EndingDate) as end_time'),
'cd.StartingDate',
'cd.EndingDate',
'cd.Duration',
'cd.Type',
'cd.Fee',
'cd.Venue',
'count (s.Id) as TotalRegistartion'
)
->join('CourseListNew as p','p.Id', '=', 'cl.ParentId','left')
->join('CourseDetailsNew as cd','cd.CourseId', '=', 'cl.Id')
->join('Student as s','s.CourseId', '=', 'cl.Id', 'left outer')
->orderBy('cl.Id','DESC')
->get();
i want to get time in 12 hours format with AM/PM but not able to find any working solution. i am not using eloquent.
Assuming you are using MySQL, you can replace the TIME function with DATE_FORMAT
$details=DB::table('CourseListNew as cl')
->select(
'cl.Title',
'p.Title as ParentTitle',
'cd.Trainer',
DB::raw('day(cd.StartingDate) as day'),
DB::raw('day(cd.EndingDate) as day_end'),
DB::raw('(cd.StartingDate) as month'),
DB::raw('year(cd.StartingDate) as year'),
DB::raw('DATE_FORMAT(cd.StartingDate, '%r') as start_time'),
DB::raw('DATE_FORMAT(cd.EndingDate, '%r') as end_time'),
'cd.StartingDate',
'cd.EndingDate',
'cd.Duration',
'cd.Type',
'cd.Fee',
'cd.Venue',
'count (s.Id) as TotalRegistartion'
)
->join('CourseListNew as p','p.Id', '=', 'cl.ParentId','left')
->join('CourseDetailsNew as cd','cd.CourseId', '=', 'cl.Id')
->join('Student as s','s.CourseId', '=', 'cl.Id', 'left outer')
->orderBy('cl.Id','DESC')
->get();
The %r format corresponds to the 12-hour time followed by AM or PM.
For more details read the documentation on: DATE_FORMAT
In SQL Server the equivalent method would be FORMAT(time, N'hh:mm tt') and you might need to refer to your own DBMS documentation for the equivalent in other flavours of SQL
For a Laravel generic solution you can of course just format the date after you've gotten the data using Carbon
use Mysql DATE_FORMAT
DB::raw('DATE_FORMAT(cd.EndingDate,'%Y-%m-%d %h:%i %p') as end_time')

Sum in laravel db query

I need to get the Sum of ProductQTY groupBy ProductID while using join, I always get an error when using db::raw, attached here is my code
$pick_list_items = DB::table('pick_list_detail')
->where('pick_list_detail.pick_list_id',$id)
->join('sale_invoices', 'pick_list_detail.sale_invoice_id','=','sale_invoices.id')
->join('sale_invoice_detail', 'sale_invoice_detail.sale_invoice_id','=','pick_list_detail.sale_invoice_id')
->select(['pick_list_detail.sale_invoice_id', 'sale_invoice_detail.product_id', 'sale_invoice_detail.product_qty', 'sale_invoice_detail.uom', 'sale_invoice_detail.uom_factor'])
->sum('sale_invoice_detail.product_qty')
->groupBy('sale_invoice_detail.product_id')
->get();
I'm using laravel 5.4
Here is the error
(2/2) QueryException
SQLSTATE[42000]: Syntax error or access violation: 1055 'fdis.pick_list_detail.sale_invoice_id' isn't in GROUP BY (SQL: select
pick_list_detail.sale_invoice_id,
sale_invoice_detail.product_id,
sale_invoice_detail.product_qty, sale_invoice_detail.uom,
sale_invoice_detail.uom_factor from pick_list_detail inner join
sale_invoices on pick_list_detail.sale_invoice_id =
sale_invoices.id inner join sale_invoice_detail on
sale_invoice_detail.sale_invoice_id =
pick_list_detail.sale_invoice_id where
pick_list_detail.pick_list_id = 1 group by
sale_invoice_detail.product_id)
$sale_invoices = DB::table('pick_list_detail')
->select(DB::raw('sum(sale_invoice_detail.product_qty) as si_count, pick_list_detail.pick_list_id , sale_invoice_detail.product_id , sale_invoice_detail.uom, sale_invoice_detail.uom_factor '))
->where('pick_list_detail.pick_list_id',$id)
->join('sale_invoices', 'pick_list_detail.sale_invoice_id','=','sale_invoices.id')
->join('sale_invoice_detail', 'sale_invoice_detail.sale_invoice_id','=','pick_list_detail.sale_invoice_id')
->groupBy('pick_list_detail.pick_list_id')
->groupBy('sale_invoice_detail.product_id')
->groupBy('sale_invoice_detail.uom')
->groupBy('sale_invoice_detail.uom_factor')
->get();
Raw Query is my solution.

Laravel 5 where condition to get pass 30 days worth of records

I have a date column in the instances table with varchar datatype stored as d-m-Y. In my where condition I am trying to fetch records for just past 30 days only.
$backdate = Carbon::parse('-30 days')->toDateString();
$date30DaysBack = Carbon::parse($backdate)->format('d-m-Y');
$adverts = DB::table('adverts')
->where(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), '>=',$date30DaysBack)
The full query
$adverts = DB::table('adverts')
->select(DB::raw('(SELECT IF(ext = \'jpeg\', CONCAT(fullpath, \'_1.\', ext), (CONCAT(fullpath,\'.\',ext))) as fullpath FROM advertsstorage where uid_dir = adverts.ad_uid ORDER BY id ASC limit 1)as fullpath, adverts.*, domains.location,instances.date'))
->join('domains','adverts.domain', '=' ,'domains.domain')
->join('advertiser_domains','domains.id', '=' ,'advertiser_domains.domain_id')
->join('advertisers','advertiser_domains.advertiser_id', '=' ,'advertisers.u_id')
->join('instances','adverts.ad_uid','=','instances.ad_uid')
->join('urls','instances.u_id','=','urls.id')
->join('sites','urls.sites_id','=','sites.id')
->where('advertisers.u_id', '=',$advertiserID)
->where(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), '>=',Carbon::now()->subDays(30)->format('d-m-Y'))
->orderBy(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), 'DESC')
->get();
Did you try DATEDIFF method
$adverts = DB::table('adverts')
->select(DB::raw('(SELECT IF(ext = \'jpeg\', CONCAT(fullpath, \'_1.\', ext), (CONCAT(fullpath,\'.\',ext))) as fullpath FROM advertsstorage where uid_dir = adverts.ad_uid ORDER BY id ASC limit 1)as fullpath, adverts.*, domains.location,instances.date'))
->join('domains','adverts.domain', '=' ,'domains.domain')
->join('advertiser_domains','domains.id', '=' ,'advertiser_domains.domain_id')
->join('advertisers','advertiser_domains.advertiser_id', '=' ,'advertisers.u_id')
->join('instances','adverts.ad_uid','=','instances.ad_uid')
->join('urls','instances.u_id','=','urls.id')
->join('sites','urls.sites_id','=','sites.id')
->where('advertisers.u_id', '=',$advertiserID)
->where(DB::raw('DATEDIFF( now(), STR_TO_DATE(instances.date,"%d-%m-%Y") )'), '<=', 30)
->orderBy(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), 'DESC')
->get();
Have you checked out the Carbon docs?
You can use the subtraction modifier for this; Carbon::now()->subDays(30);.
Would look something like this in your code:
$adverts = DB::table('adverts')->where(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), '>=', Carbon::now()->subDays(30)->format('d-m-Y'))
Try this.
Carbon has subDays function by which you can get past 30 days data
$date30DaysBack= Carbon::now()->subDays(30)->format('d-m-Y');
$today = Carbon::now()->format('d-m-Y');
$adverts = DB::table('adverts')
->whereBetween(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'),[$date30DaysBack,$today])->get()

Resources