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 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');
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
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();
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.
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.