How to update DATETIME column in mysql
Tried using: (and many others)
I do not really care how the date is formatted in the database however need to be able to update the current row with the 01/01/2001 01:01 format
update contacts set replydate=STR_TO_DATE('1/9/2020 13:32', '%m/%d/%Y hh:mm') where id='3';
The date is not the current date, these are all different dates from a spread sheet, that all have the same formatting.
MariaDB [ddcontactsdb]> describe contacts;
+----------------+-----------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-----------------+------+-----+-------------------+-----------------------------+
| replydate | datetime | YES | | NULL | |
+----------------+-----------------+------+-----+-------------------+-----------------------------+
You must use this format:
update contacts set replydate=STR_TO_DATE('1/9/2020 13:32', '%m/%d/%Y %H:%i') where id='3';
because m stands for month and i for minutes, also H for hour 00-23.
Related
I want to weekly update a field in a MySQL table "Persons", with the avg of two fields of the "Tasks" table, end_date and start_date:
PERSON:
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| average_speed | int(11) | NO | | 0 | |
+----------------+-------------+------+-----+---------+-------+
TASKS:
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| person_id | int(11) | NO | | NULL | |
| start_date | date | NO | | NULL | |
| end_date | date | NO | | NULL | |
+----------------+-------------+------+-----+---------+-------+
(tables are not complete).
average_speed = AVG(task.end_date - task.start_date)
Now, the Tasks table is really big, and ** I don't want to compute the average on every task for every person every week**. (That's a solution, but I'm trying to avoid it).
What's the best way to update the average_speed?
I thought about adding two columns in the person's table:
"last_count": count of computed tasks since now for each person
"last_sum": last sum of (end_date - start_date) for each person
So that on a new update i could do something like average_speed = (last_sum+new_sum) / (last_count + new_count) where new_count is the sum of the tasks in the last week.
Is there a better solution/architecture?
EDIT:
to answer a comment, the query I would do is something like this:
SELECT
count(t.id) as last_count,
sum(TIMESTAMPDIFF(MINUTE, t.start_date, t.end_date)) as last_sum
avg(TIMESTAMPDIFF(MINUTE, t.start_date, t.end_date))
from tasks as t
where t.end_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 WEEK) AND CURDATE()
And i can rely on a php script to get result and do some calculations
Having a periodic update to the table is a bad way to go for all the reasons you've listed above, and others.
If you have access to the code that writes to the Tasks table, that’s the best place to put the update. Add an Average field and calculate and set the value when you write the task end time.
If you don’t have access to the code, you can add a calculated field to the table that shows the average and let SQL figure it out during the execution of a query. This can slow queries down a little, but the data is always valid and SQL is smart enough to only calculate that value when it is needed.
A third (ugly) option is a trigger on the table that updates the value when appropriate. I’m not a fan of triggers because they hide business logic in unexpected places, but sometimes you just have to get the job done.
My table schema looks like this:
+--------------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50 | NO | | 0 | |
| modified | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| created | timestamp | NO | | CURRENT_TIMESTAMP | |
+--------------------+--------------+------+-----+-------------------+-----------------------------+
I want to get a count of the names and group by number of names modified by day at the moment I can only group by the full date including the timestamp eg:
SELECT name, count(*) FROM mytable GROUP BY modified
Thanks in advance.
Use MySQL DATE() function to extract the date from the timestamp:
SELECT name, count(*) FROM mytable GROUP BY DATE(mytable.modified);
The DATE() function extracts the date value from a date or datetime expression.
Dependant upon what you mean by day, you have a few options;
Here's your cheat sheet.
DAYNAME(date) for the day of the week (Mon-Sun)
DAYOFMONTH(date) for the day of the month (1-31)
DAYOFWEEK(date) for the day of the week (1-7)
DAYOFYEAR(date) for the day of the year (1-365)
Edit:
If you want to group by the entire date (as opposed to a particular day), ignoring the time you can use
DATE_FORMAT(date, format)
The full list of format specifiers can be found at the above link, but what you'll probably need is:
Date_FORMAT(date, '%Y-%m-%d')
This will format the date as 'YYYY-MM-DD' and you can group by that.
You can use this query or a version of it
SELECT DATE_FORMAT(modified,"%Y-%m-%d") as date_string, count(1) FROM mytable group by date_string;
In MySQL I have a table node_weather:
mysql> desc node_weather;
+--------------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+-------------------+-----------------------------+
| W_id | mediumint(9) | NO | PRI | NULL | auto_increment |
| temperature | int(10) | YES | | NULL | |
| humidity | int(10) | YES | | NULL | |
| time | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
Now what I need to do is the following: for every two hours of the current day (00:00:00, 02:00:00, ..., 24:00:00) I want to get a temperature. Normally the query could be like that:
mysql> SELECT temperature
-> FROM node_weather
-> WHERE date(time) = DATE(NOW())
-> AND TIME(time) IN ('00:00:00','02:00:00','04:00:00','06:00:00','08:00:00','10:00:00','12:00:00','14:00:00','16:00:00','18:00:00','20:00:00','22:00:00','24:00:00');
In the ideal case, I should get a result as 12 rows selected and everything would be fine. But there are two problems with it:
The table does not include the data for thw whole day, so for example the temperature for the time '24:00:00' is missing. In this case, I would like to return NULL.
The table sometimes record the data with the timestamp like '10:00:02' or '09:59:58', but not '10:00:00'. To resolve this case, I would like to add the offset to all the values in IN expression (something like that ('10:00:00' - offset, '10:00:00' + offset)) and it would select always just ONE value (no matter which one) from this range.
I know it is kind of awkard, but that is how my boss wants it. Thanks for help!
Okay, a bit more precise than what I wrote in comments:
EDIT: Had a bug. Hopefully this doesn't.
SELECT
time,
deviation,
hour,
temperature
FROM (
SELECT
time,
ROUND(HOUR(time) / 2) * 2 AS hour,
IF(HOUR(time) % 2,
3600 - MINUTE(time) * 60 - SECOND(time),
MINUTE(time) * 60 + SECOND(time)
) AS deviation,
temperature
FROM node_weather
WHERE DATE(time) = DATE(NOW())
ORDER BY deviation ASC
) t
GROUP BY hour
ORDER BY
hour ASC
Basically, group on intervals like 09:00:00 - 10:59:59 (by rounding hour/2), then sort ascending by those intervals, and within the interval by the distance to the center of the interval (so we choose 10:00:00 over 09:00:00 or 10:59:59).
I'm having an interesting issue with Mysql DATE format.
I have this table :
| id | int(11) | NO | PRI | NULL | auto_increment |
| file_path | varchar(255) | YES | | NULL | |
| date_export | date | YES | | NULL | |
When i'm updating a row using the date function : NOW(), the date is updated with this format :
'2014-01-23'
But when i'm using another date format, like hand-written one like :
update backup_conf_allied set date_export='2014-23-01' where file_path='IDF-952584-SW1' ;
The date_export column transforms into :
'0000-00-00'
Warning table tells me that :
| Warning | 1265 | Data truncated for column 'date_export' at row 3628 |
Why? The date format is the same as NOW() function.
Thanks.
Posted query
update backup_conf_allied set `date_export='2014-23-01'` where file_path='IDF-952584-SW1' ;
What it should be
update backup_conf_allied set `date_export='2014-01-23'` where file_path='IDF-952584-SW1' ;
MySQL Support DATE format as 'YYYY-MM-DD' , Year then Month then Date, So you are updating a Date column with wrong value "2014-23-01" , There are only 12 months in year, you are using month 23 which is invalid that's MySQL is converting it to ZERO DATE (0000-00-00)
I had a similar problem recently, my issue was that I was trying to upload a datetime object as a date object. Although that's not the same issue that Gui O was having, if you run into this, make sure that you're actually trying to upload a date object.
I'm having this same problem but for a different reason. My MySQL column has a datetime type, but my datetime values are from Python, and they look like this: `'2021-04-01 03:58:50.088087'.
So the result is to truncate before the period:
t = t[0:19]
e.g.:
>>> datetime.datetime.now().isoformat()
'2021-04-03T08:28:41.602373'
>>> datetime.datetime.now().isoformat()[0:19]
'2021-04-03T08:28:44'
>>>
For Example
select date_format(date(credit_date),'%Y-%m-%d') from product where date(credit_date) >= date '2012-11-02' and date(credit_date) <= date '2013-11-02'
How to Fetch the Column From Date1 To Date2
And Db Structure is
+-----------------------------------------+
| credit_date |
+-----------------------------------------+
| 21/09/2013 |
| 22/09/2013 |
| 23/09/2013 |
| 24/09/2013 |
| 25/09/2013 |
| 26/09/2013 |
| 27/09/2013 |
| 28/09/2013 |
+-----------------------------------------+
It look like your credit_date is a varchar type with another date format, if so try this:
select date_format(str_to_date(credit_date,'%d/%m/%Y'), '%Y-%m-%d') as dt
from product
where str_to_date(credit_date,'%d/%m/%Y') >= '2012-11-02'
and str_to_date(credit_date,'%d/%m/%Y') <= '2013-11-02'
The default format for mysql is Y-m-d you don't need to convert it on the where clause. Unless your database is configured to have a specific format. As your credit_date seems to be a varchar you have to convert it first to date then test it.
See it here on fiddle: http://sqlfiddle.com/#!2/8b379/9