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.
Related
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();
I am using HTML input type="date" to allow users to input appointment dates.
Now I want to query the database and show all appointments that are "today" and in the future.
Not dates that have already passed.
Here is my SQL Script
$today = date('d-m-Y');
$sql = "SELECT *
FROM `client1`
WHERE `client` = '$customer'
AND DATEDIFF('$today', `date`) >= 0
ORDER BY `id` DESC";
Can someone guide me as to how I can achieve this?
I have seen several directions online but I want to have the sorting done at the moment of query.
I have solved the issue!
My date() format was incorrect because HTML input type="date" inserts YYYY-MM-DD into the database =/
$today = date('d-m-Y');
should be
$today = date('Y-m-d');
My operator >= should have been <= to show today and future dates.
Thanks everyone for the help. I should have tried fixing it for 5 more minutes before posting.
Why are you using PHP to compare dates in the database? I assume its a date field so you can use MySQL to do it for you:
SELECT *
FROM `client1`
WHERE `client` = '$customer'
AND DATEDIFF(date_format(now(), '%Y/%m/%d'), `date`) >= 0
ORDER BY `id` DESC
None of the responses have specified sargable predicates. If you perform an operation on a column in the where clause, there is no discernible stopping point.
where ... some_function( some_field ) = some_constant_value ...
Even if some_field is indexed, a complete table scan must be performed because there is no way to know if the output of the operation is also ordered.
From my understanding the date column is in a sortable form -- either a date field or a string in lexically sortable format 'yyyy-mm-dd'. That being the case, don't do any operation on it.
where ... some_field >= now() ...
Thus the system can use the result of now() as a target value to find exactly where in the index to start looking. It knows it can ignore all the rows with indexed values "down" from the target value. It has to look only at rows with indexed values at or "up" from the target value. That is, it performs an index seek to the correct starting point and proceeds from there. This could mean totally bypassing many, many rows.
Or, to put it bluntly, ditch the datediff and do a direct comparison.
I'm trying to query a database with a between 2 dates... The problem is the column that I am querying contains dates that are currently formatted like this "01/01/2014" (dd/mm/yyyy) with a column type of VARCHAR.
At the moment, I can't convert the column to a date type.
Basically when I query the table because it's not set to date type the between query doesn't return the correct rows...
Has anyone else come across this problem, is there something I can change within the query?
$this->db->where('IssueDate >=', '02/12/2013');
$this->db->where('IssueDate <=', '22/01/2014');
$query = $this->db->get('MYTABLE');
Thanks guys.
The solution is to use str_to_date():
$this->db->where("str_to_date(IssueDate, '%d/%m/%Y') >=", "'2013-12-92'");
$this->db->where("str_to_date(IssueDate, '%d/%m/%Y') <=", "'2014-01-22'");
$
You may not have any control over the database. But you do have control over your own constants. You should get used to the ISO standard YYYY-MM-DD for such constants -- unambiguous and accepted correctly by most databases.
I might suggest creating a view on the table in the database that transforms the string date columns you have into the following format... YYYYMMDD
That format is sortable and can easily be compared versus other similar formatted dates - you can even do date arithmetic with it.
Keep in mind that a view does not copy the table or add any performance overhead. It is often a good idea to access any table through a view even if initially you do not need to perform any manipulations on the underlying table - it will help if you later find you do need to perform them.
use BETWEEN clause with STR_TO_DATE(). Check below code:-
$wh = STR_TO_DATE(`IssueDate`,'%d/%m/%Y')." between '02/12/2013' and '22/01/2014'";
$this->db->where($wh);
Expect it'll give You perfect result.
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'll explain my goal first: I want the user to query the database, and return rows only if those rows have been updated since their last query. No sense returning data they'd already have. So I created a column called 'lastupdated', a timestamp type which autoupdates every time any content in the row is updated. This works fine. Now, I want to form the query correctly. The user will have their previous query's timestamp saved, and via php will use it to compare their previous query's time with the time each row has been updated. If the row was updated after their last query, the row should be returned.
I made something like this,
SELECT * FROM users WHERE '2011-02-26 01:50:30' <= lastupdated
but its obviously much too simple. I checked the MySQL manual and found this page MySQL Time/Date Page. I'm sure the answer is here, but I've read through it any nothing really makes sense. I have a timestamp in the same format used by the MySQL timestamp type, but I don't know how I will compare them. Thank you very much for your help.
That query is exactly how you'd do it. As long as a stringified date-time is in MySQL's preferred format (yyyy-mm-dd hh:mm:ss), then it will be internally converted into a datetime value, and the comparisons will go ahead.
You'd only need the date/time functions you found if you want to do something more complicated than simple "greater/less than/equal" type comparison, e.g. "any records that have a December timestamp".
As Marc said, your code should work. But you probably want to do this programmatically with a variable for the time instead of the literal.
If you don't have the date-time specified as a string, but rather as a timestamp (e.g. from using the php time() function), then you can use the following query:
$query = "SELECT * FROM users WHERE FROM_UNIXTIME(" . $timestamp . ") <= lastupdated";
The key is the FROM_UNIXTIME() MySQL function.