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.
Related
I have an array of dates for example:
array:5 [
0 => "2021-12-06"
1 => "2021-12-07"
2 => "2021-12-08"
3 => "2021-12-09"
4 => "2021-12-10"
]
And I have a database table whose structure is like:
id
clinic_id
start_date
end_date
start_date and end_date are fields of datetime.
How to get all data from this table that aren't at the array, using laravel eloquent?
Are your dates strings or Carbon instances? You can match on a string with a LIKE query, since we're not checking the times.
If they're Carbon instances, first use $str = $date->format('Y-m-d'); first.
$query = Clinics::query();
foreach ($dates as $date) {
$query->where('start_date', 'not LIKE', $date.'%')
->where('end_date', 'not LIKE', $date.'%');
}
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
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'm having a problem when searching a datetime column with a string.
I'm using codeigniters insert_batch, but I'm sure it's the same if I use insert. This is an example of the data I'm inserting:
$valor_log_proceso = array(
'id_interno' => 21656,
'proceso_id' => 1,
'fecha_inicio' => '2015-12-02T09:04:59.884',
'fecha_fin' => '2015-12-02T09:20:10.884',
'equipo' => "EQUIPOPC",
'usuario_id' => 2,
'log_envio_id' => 10
);
In the mysql db 'fecha_inicio' and 'fecha_fin' are datetime colmuns.
'fecha_inicio' and 'fecha_fin' values in every single $valor_log_proceso array are strings retrieved from a request.
When I try to look for that data with a get_where
$valor_log_proceso = array(
'id_interno' => 21656,
'proceso_id' => 1,
'fecha_inicio' => '2015-12-02T09:04:59.884',
'fecha_fin' => '2015-12-02T09:20:10.884',
'equipo' => "EQUIPOPC",
'usuario_id' => 2
);
$result = $this->db->get_where($table_name, $valor_log_proceso)->result_array();
$result is an empty array.
Then I check the database and see that the dates where truncated/ceiled to:
fecha_inicio: 2015-12-02 09:05:00
fecha_fin: 2015-12-02 09:20:11
So the question is why does that happen?
How can I search correctly for rows in the table?
The reason this is happening is that a DATETIME column can only have this pattern of data. As you see, it is stripping out the 'T' as well.
See https://dev.mysql.com/doc/refman/5.6/en/datetime.html
The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'
In order to create the query correctly, you will have to change your array to match the same pattern...
'fecha_inicio' => '2015-12-02 09:04:59',
'fecha_fin' => '2015-12-02 09:20:10',
ADDITION
Here is a function to manipulate the current format to the needed format
function format($x){
$x = preg_replace('/[T]/', ' ', $x);
$y = explode(".", $x);
return $y[0];
}
$x = format('2015-12-02T09:04:59.884');
echo $x; // Prints 2015-12-02 09:04:59
I am trying to create a get statements function and I have some problems defining the date range.
The data will be passed via get method in the following format: ?year=yyyy&month=mm
The relevant column of the table has datetime type (2012-02-01).
I checked the TimeHelper class and more particularly the TimeHelper::daysAsSql($begin, $end, $fieldName, $timezone = NULL) but i am not sure if it applies for this case.
I was thinking if i can create a date in the format of Y-m using the two variables year and month and then use it in the conditions for retrieving the data but I am sure there is a more efficient and proper way. Could anyone help?
$user_id = $Client['Client']['id'];
$year = $this->request['url']['year'];
$month = $this->request['url']['month'];
//$date_created = date('Y-m');
if (!empty($user_id) && (!empty($date_created))) {
$Reports = $this->Report->find('all', array(
'fields' => array('amount','currency','date_created','invoice_no'),
'conditions' => array(
'Report.client_id'=> $user_id,
'Report.date_created >=' => $date_created,
'Report.date_created <=' => $date_created
),
)
);
MONTH(dateColumn) Returns an integer that represents the month of the specified date.
YEAR(dateColumn) Returns an integer that represents the year of the specified date.
InCakephp use as
$user_id = $Client['Client']['id'];
$year = $this->request['url']['year'];
$month = $this->request['url']['month'];
//$date_created = date('Y-m');
if (!empty($user_id) && (!empty($date_created))) {
$Reports = $this->Report->find('all', array(
'fields' => array('amount','currency','date_created','invoice_no'),
'conditions' => array(
'Report.client_id '=> $user_id,
'MONTH(date_created ) >='=> $month,
'YEAR(date_created ) <=' => $year
),
)
);