Cakephp MYSQL query: SELECT where date is greater than - php

I have to run a MYSQL select query where the query returns all values that have the beginning date 10 days after today. I have tried these two methods none of which seem to work, where do I need to make a change?
$fix_d_table = TableRegistry::get('fixed_departures');
$f_dates_march = $fix_d_table ->find("all")
->where(['trek_id' => 3])
->andWhere(['month(date_from)' => 03])
->andWhere(['date_from' >= date("Y-m-d",strtotime("+10 days"))])
->order(['date_from'=>'asc'])
->select(['date_from', 'date_to', 'seats_available','id'])
->toArray();
$fix_d_table = TableRegistry::get('fixed_departures');
$f_dates_march = $fix_d_table ->find("all")
->where(['trek_id' => 3])
->andWhere(['month(date_from)' => 03])
->andWhere(['date(date_from)' >= date("Y-m-d",strtotime("+10 days"))])
->order(['date_from'=>'asc'])
->select(['date_from', 'date_to', 'seats_available','id'])
->toArray();

Try below one
$fix_d_table = TableRegistry::get('fixed_departures'); $f_dates_march
= $fix_d_table ->find("all")
->where(['trek_id' => 3])
->andWhere(
function ($exp) {
return $exp->or_([
'date_from <=' => date('Y-m-d', strtotime("+10 days")),
'date_from >=' => date('Y-m-d')
]);
})
->order(['date_from'=>'asc'])
->select(['date_from', 'date_to', 'seats_available','id'])
->toArray();

should be
'date_from >=' => date("Y-m-d",strtotime("+10 days"))
if you can rely on mysql server date you can use NOW() inside your query
->where(function($exp, $q) {
return $exp->gte($q->func()->dateDiff([
'date_from ' => 'identifier',
$q->func()->now() ]), 10);
});
this will give you the following SQL condition
WHERE
(
DATEDIFF(date_from , NOW())
) >= 10

Related

How to filter by month and year on updateOrCreate in laravel?

How to filter created_at with month and year in Laravel's updateOrCreate()?
$statistik = Statistik::updateOrCreate(
[
'kode_kantor' => $map->kode_kantor,
'created_at' => whereYear('created_at', '=', date('Y-m-d')),
'created_at' => whereMonth('created_at', '=', date('Y-m-d'))
]
)->increment('poin_kunjungan');
What you are looking for cannot be done by updateOrCreate(). You would have to do a manual check. For example:
$statistik = Statistik::where('kode_kantor', $map->kode_kantor)
->whereYear('created_at', '=', date('Y-m-d'))
->whereMonth('created_at', '=', date('Y-m-d'))
->first();
if(! $statistik) {
$statistik = Statistik::create([
'kode_kantor' => $map->kode_kantor
]);
}
$statistik->increment('poin_kunjungan');

Laravel SQL Query Returning Duplicates

I am trying to increase the speed of my Laravel 5.4 sql query by using joins, which I've never used before. I currently have the query working and returning results, my issue is that I get like each results around 8 times. Ex: I get the same 2001 Chevrolet Silverado 8 times in my array. If anybody could help me out I would really appreciate it. Thanks
My query + collection:
$tmp = DB::table('inventories'
)->join(
'vehicles', 'vehicles.id', '=', 'inventories.id'
)->join(
'vimages', 'vimages.vehicle_id', '=', 'inventories.id'
)->where(
'inventories.dealer_id', '=', $dealer_id
)->where(
'inventories.is_active', '=', 1
)->where(
'inventories.is_deleted','=', 0
)->select(
'inventories.stock_number','inventories.vehicle_id','vehicles.year','vehicles.make','vehicles.model','vehicles.vin','inventories.vehicle_status',
'inventories.cost','inventories.search_meta','vimages.name'
);
$data = collect();
$pmt = $tmp->get();
// return json_encode( $pmt );
// logger( sprintf('# of rows returned: %s', $pmt->count() ) );
$pmt->each( function($row) use(&$data) {
// logger( sprintf('Row : %s', $row->toJson() ));
$data->push( array(
'stock_number' => $row->stock_number,
'vehicle_id' => $row->vehicle_id,
'year' => $row->year,
'make' => $row->make,
'model' => $row->model,
// 'trim' => $row->trim,
'vin' => $row->vin,
'status' => $row->vehicle_status,
// 'purchase_price' => $row->purchase_price,
'cost' => $row->cost,
// 'retail_price' => $row->retail_price,
'search_meta' => $row->search_meta,
// 'images' => $row->getFirstImage()
'images' => $row->name
// 'interior_color' => $row->vehicle()->first()->interior_color,
// 'exterior_color' => $row->vehicle()->first()->exterior_color,
// 'firstImg' => $row->getFirstImage()
// 'images' => Vimage::select('vehicle_id','name'
// )->where(
// 'dealer_id', '=', $row->dealer_id
// )->where(
// 'vehicle_id', '=', $row->vehicle_id
// )->limit(1)->get()
));
});
Example of my array:
https://i.imgur.com/FOphST8.png
I don't see your db table but I think there is problem in first join statment:
you should use
->join('vehicles', 'vehicles.id', '=', 'inventories.vehicle_id' )
instead of
->join('vehicles', 'vehicles.id', '=', 'inventories.id' )
also second join should be like
->join('vimages', 'vimages.vehicle_id', '=', 'vehicles.id')
instead of
->join('vimages', 'vimages.vehicle_id', '=', 'inventories.id')
It sounds trivial but this should work:
$tmp = DB::table('inventories'
)->join(
'vehicles', 'vehicles.id', '=', 'inventories.id'
)->join(
'vimages', 'vimages.vehicle_id', '=', 'inventories.id'
)->where(
'inventories.dealer_id', '=', $dealer_id
)->where(
'inventories.is_active', '=', 1
)->where(
'inventories.is_deleted','=', 0
)->selectRaw("DISTINCT inventories.stock_number, inventories.vehicle_id,
vehicles.year, vehicles.make, vehicles.model, vehicles.vin,
inventories.vehicle_status, inventories.cost,
inventories.search_meta, vimages.name"
);
Update: forgot to delete the single quotes in selectRaw
Figured it thanks to #Devon. Added another where statement to query to only get first image.
Thanks
)->where('vimages.sequence','=', 0

Symfony doctrine group by max date timestamp

I would like to select values from table o by some conditions and grouped by groupKey. This query is working fine, but now query return first grouped value for my. I need to retrieve grouped values with MAX timestamp.
An example if there are two or more values with groupKey I need that one where o.createdAt value is newer.
$qb = $this->createQueryBuilder('order');
$expr = $qb->expr();
return $qb
->select('order, (CASE WHEN order.tsmOrderNumber IS NOT NULL THEN order.tsmOrderNumber ELSE order.id END) as groupKey')
->where('order.user =:user')
->andWhere('order.status =:status')
->andWhere(
$expr->orX(
$expr->andX(
$expr->isNotNull('order.wayBillNumber'),
$expr->neq('order.wayBillNumber', "''"),
$expr->between('order.createdAt', ':dateFrom', ':dateTo')
),
$expr->andX(
$expr->orX(
$expr->isNull('o.tsmNumber'),
$expr->eq('o.tsmNumber', '\'\'')
),
$expr->between('order.createdAt', ':dateFrom2', ':dateTo')
)
)
)
->setParameters(
[
'status' => Order::STATUS_COMPLETED,
'user' => $user,
'dateFrom' => (new \DateTime())->modify('-2 month'),
'dateFrom2' => (new \DateTime())->modify('-6 month'),
'dateTo' => new \DateTime()
]
)
->groupBy('groupKey')
->orderBy('order.createdAt', 'DESC')
->getQuery()
->getResult();

How to bind datetime field between two string value

I have method like this :
public function getCustomDateOrders(string $startDay,string $endDay,string $food) :array
{
$result = $this->_em->createQueryBuilder()
->select
(
'OrderEntity.name'
'OrderEntity.created'
)
->from($this->entityClass , 'OrderEntity')
->leftJoin(
'Directory\Food',
'Food',
'with',
'Food.id = OrderEntity.FoodId '
)
->where("Food.id =:food")
->andWhere("OrderEntity.status =:active")
->andWhere("startDate<:OrderEntity.orderCreated >:endDay")
->getQuery()
->setParameters([
"food" => $food,
"active" => 1,
"startDate" => $startDay,
"endDay" => $endDay
])
->getScalerResult();
->getScalarResult();
}
I have couple of values :
$startDay is equal to "2016-010-17 00:00:00" (string)
$endDay is equal to "2016-10-03 00:00:00" (string)
And also order.created (one of order's fields) is datetime.
I want to fetch order from order entity which has created field is between $startDay and $endDay. How to solve it?
Use between:
public function getCustomDateOrders(string $startDay,string $endDay,string $food) :array
{
$result = $this->_em->createQueryBuilder()
->select
(
'OrderEntity.name'
'OrderEntity.created'
)
->from($this->entityClass , 'OrderEntity')
->leftJoin(
'Directory\Food',
'Food',
'with',
'Food.id = OrderEntity.FoodId '
)
->where("Food.id =:food")
->andWhere("OrderEntity.status =:active")
->andWhere("OrderEntity.orderCreated between :startDay and :endDay")
->setParameters([
"food" => $food,
"active" => 1,
"startDay" => $startDay,
"endDay" => $endDay
])
->getQuery()
->getScalerResult();
}
And that is why we don't store dates as strings. You can still convert the string inside the query, so don't just turn off the computer yet.
Use the str_to_date() function:
Lets translate it into SQL:
select * from yourtable
where created > str_to_date(start_day, '%Y-%m-%d %H:%i:%s')
and created < str_to_date(end_day, '%Y-%m-%d %H:%i:%s')
There we go. Give me all the rows which where created after the start_date and before the end date.
The better way would probabbly be converting your strings to dates and the use between like sugested.

How to get sum of total counts with most recent hourly / daily / weekly / yearly interval in cakephp 3?

I've a table as following-
Now I need to make report of total number of counts in every hour, week, month and year. It may have sum 0 but should be include on the result. For example I need the result as follows-
$hourlyResult = array(
'00:01' => '5',
'00:02' => '9',
'00:03' => '50',
'00:04' => '5',
..............
..............
'00:55' => '95',
'00:56' => '0',
'00:57' => '20',
'00:58' => '33',
'00:59' => '5',
);
$weeklyResult = array(
'SAT' => '500',
'SUN' => '300'
.............
.............
'FRI' => '700'
);
How can I build the query in cakephp 3? I got the following link but can't go so far.
GROUP BY WEEK with SQL
What I've done-
$this->loadModel('Searches');
$searches = $this->Searches
->find('all')
->select(['created', 'count'])
->where('DATE(Searches.created) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)')
->group(WEEK(date))
->hydrate(false)
->toArray();
pr($searches);
Here is how you can do it.
Sum By Year
$query = $this->Searches->find();
$query = $this->Searches
->find()
->select([
'total_count' => $query->func()->sum('count'),
'year' => $query->func()->year(['created' => 'literal'])
])
->group(['year'])
->hydrate(false);
Or
$query = $this->Searches
->find()
->select(['total_count' => 'SUM(count)', 'year' => 'YEAR(created)'])
->group(['year'])
->hydrate(false);
Sum By Day Of Week
$query = $this->Searches->find();
$query = $this->Searches
->find()
->select([
'total_count' => $query->func()->sum('count'),
'day_of_week' => $query->func()->dayOfWeek('created')
])
->group(['day_of_week'])
->hydrate(false);
Or
$query = $this->Searches
->find()
->select(['total_count' => 'SUM(count)', 'day_of_week' => 'DAYOFWEEK(created)'])
->group(['day_of_week'])
->hydrate(false);
The same way you can get total sum by hour or month.
Here you can read about CakePHP > Using SQL Functions and date and time functions in MySQL.

Categories