In my database a have a table with a column called date. In the date columns are datetime entries stored. Now I want to write a query that gets me all entries from a day.
Now If I do it like that I obviously get just the records with exact same timestamp
$date = Carbon::now()->startOfDay();
Task::where('date', $date)->get()->all();
But I need all records where the date is the same, no matter which timestamp they have
Laravel has a whereDate function, which is what you're looking for:
Task::whereDate('date', $date->toDateString())->get();
However, Eloquent may cause some issues since you have the column named date, and it automatically scopes the where clauses for you. In that case, you'll need a raw command:
Task::whereRaw('DATE(`date`) = ?', [$date->toDateString()])->get();
Related
I have a table in the database where the records contain a start_date and an end_date. An example of the data format is:
"13/03/2020"
How can I fetch all records for the week? I have tried the code below. However, it does not return any data.
$date = Carbon::now()->format('d/m/Y');
$dateInWeek = Carbon::now()->addDays(7)->format('d/m/Y');
$holidays = Holiday::where('start_date', '>=', $date)
->where('end_date', '<=', $dateInWeek)->get();
Probably correct solution is to change string to datetime in db, if it is not an opinion then you can create custom function in database that will handle strings in way you want.
You shouldn't use string when you can use date / datetime column type.
But that being said - it's not always up-to us to be able to change DB structure.
Solution 1
Depending on what SQL you are using there is usually function to cast string to date.
For example MySQL: STR_TO_DATE(string, format)
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_str-to-date
Solution 2
You can make array containing all dates of week using Carbon.
then in query: ->whereIn('start_date', $datesArray)->whereIn('end_date', $datesArray)
I'd still suggest changing column type to date if possible
I have a model ProductSell with a column date which type is varchar and format is d/m/Y .
Suppose I have two date 31/03/2019 and 01/04/2019 .
I want to fetch data between these dates
I am trying like
$productsale=ProductSell::whereBetween('date',[$request->from,$request-
>to])->get();
when date is
31/03/2019 and 01/04/2019
this is not working but when date is
01/03/2019 and 31/03/2019 it working fine
Is there any solution ?
If at all possible, change the datatype from a varchar to a date, datetime or timestamp. The problem here is that the database doesn't understand how to order the date columns chronologically -- since it thinks it's dealing with standard text and wants to sort them alphabetically. Using datetime allows it to sort the rows by date a select the subset you want.
Fortunately you can often just change the datatype of the column and as long as the values are in a standard format (And your table isn't millions and millions of records) it will usually convert them just fine. I'm assuming you're using mysql here, but most databases should have something similar.
ALTER TABLE <tableName> MODIFY <columnName> datetime;
Of course, I'd suggest making a copy of the table and trying out the conversion on that first -- just to be safe.
Im trying to avoid reworking a bunch of code. Keep in mind im using the yii framework. I have a table in mysql database that has one field name datetime is the type is datetime. So it holds something like this.
2014-01-31 09:20:00
I need to query that table with only the date along to find all records for that date.
$date = 2014-01-31
$app = Appointments::model()->findAllByAttributes(array('datetime'=>$date));
My problem is that it will not return anything because the time is also included in the datetime record. Is there a way for me to either add a universal time that mysql will read and select anytime or can I do some kind of query that will just ignore the time and just select the dates?
You can use a condition datetime BETWEEN '2014-01-31 00:00' AND '2014-01-31 23:59'. (By the way, consider a better name for that column.)
But you cannot express that with findAllByAttributes, you will need something like this:
$date = '2014-01-31'; // the date
$start_time = $date . ' 00:00:00';
$end_time = $date . ' 23:59:59';
$apps = Appointments::model()
->findAll('datetime BETWEEN :start_time AND :end_time', array(
':start_time' => $start_time,
':end_time' => $end_time,
));
Edit: I see other answers recommending a different approach - asking MySQL to convert its stored value to match your format. That does not scale! If you have thousands of records, this does not make a significant difference, but if you get a few orders of magnitude more than that, you'll see nasty delays.
If you just ask MySQL to match a value without converting it like I suggested, you can put an index on this column and get answers very quickly.
If you ask MySQL to convert the stored values, it has to convert each record in the table to determine if it's a match. Other databases can put an index on the converted value, but MySQL cannot, therefore each time this query is run, it has to convert each record again...
$sql = ".........where date_format(datetime,'%Y-%m-%d')={$date}";
$app = Appointments::model()->findAllBySql($sql );
I have a DATETIME string and I need only the DATE in my script to perform some searches in my database. Currently, I have two scenarios in my mind, but don't know which of them is faster.
The first scenario:
In my MYSQL database, I have two columns: datetime (which is a DATETIME type) and date (which is a DATE type).
Then, in my PHP script, each time I save a record, I will insert my known string to the datetime field, and then convert it to fit the date field (I was thinking of something like: $date = date("Y-m-d", strtotime($datetime))).
This way, all the necessary pieces are stored in my database and I can retrieve them on the fly (both the datetime and the date fields).
The second scenario:
The MYSQL database should consist only of the datetime column.
My PHP script will insert the known string to the datetime field without any other modifications.
And when I retrieve my data, I would do something like: SELECT datetime, DATE(datetime) FROM ...
Conclusion
Which of these scenarios is faster and therefore should be used? Should date formats be made on save or on retrieve? Is MYSQL faster than PHP on formatting dates? Is it better to store everything in the database and retrieve as it is, or store only the minimum and format on retrieve? Which of these scenarios is the best practice?
Thank you!
It depends of your usecases:
If you are only going to need the date for reading, then go with a single datetime column, conversion from datetime to date is cheap enough.
If you are going to select rows at a given date (like WHERE date = '2011-08-01'), then go for a date column, as this will allow mysql to use the indexes on the date column if you have added one.
If you are going to select rows in a date range, then go for a datetime column. You could do things like WHERE datetime >= '2011-08-01' AND datetime < '2011-08-16'.
The second one is the best and fast as you are getting the value based on the requirement. Rather getting some value and working on it later.
imho
datetime, or even unsigned integer (unix timestamp) is better for range filtering
datetime allow date-time function, it could be useful for aggregate function
avoid formatted data from mysql (that's mean raw)
anything related to presentation is PHP duty
Definitely depends on your situation - if you will be reading (a lot) more than writing, you can store both. But I'd go for storing one field (datetime) and convert that, either in PHP or while retrieving it from MySQL (convert datetime to char in the format you like)
I have a column of type datetime in MySql table. Stored values are like this:
2008-02-15 17:21:56
2008-02-15 17:22:02
2008-02-15 17:22:03
Now I want to query some records based on this column but I have only date part not time part.
So I am querying like this in zend.
$select->where('tableName.columnName = ?', '2008-02-15' );
But it does not match any record. How can I query without time part.
Thanks
try this WHERE DATE(tableName.columnName) = '2008-02-15'
The answer #Shota has provided will work, however it will prevent MySQL from using any indexes on the datetime column due to the DATE function having to be called on every row of the table to see if it matches.
If you hard code the time range into the query it will give the same result and still allow indexes to be used.
eg. $select->where('tableName.columnName >= ? AND tableName.columnName <= ?', '2008-02-15 00:00:00', '2008-02-15 23:59:59' );
Please note i may have the php syntax wrong but you should get the idea.