MySQL is giving me a hard time to update a timestamp column
mysql> describe payments;
+---------+------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+-------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(10) unsigned | NO | | NULL | |
| cat_id | int(10) unsigned | NO | | NULL | |
| amount | int(11) | NO | | NULL | |
| time | timestamp | NO | | CURRENT_TIMESTAMP | |
+---------+------------------+------+-----+-------------------+----------------+
5 rows in set (0.00 sec)
I would like to set the time of record 1 to Jan 1st 2040
mysql> select * from payments;
+----+---------+--------+--------+---------------------+
| id | user_id | cat_id | amount | time |
+----+---------+--------+--------+---------------------+
| 1 | 1 | 4 | 40 | 0000-00-00 00:00:00 |
| 2 | 1 | 3 | 30 | 2030-01-01 00:00:00 |
+----+---------+--------+--------+---------------------+
2 rows in set (0.00 sec)
But it gives me an out of range warning
mysql> update payments set time='2040-01-01 00:00:00' where id=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 1
mysql> show warnings;
+---------+------+-----------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------+
| Warning | 1264 | Out of range value for column 'time' at row 1 |
+---------+------+-----------------------------------------------+
1 row in set (0.00 sec)
Am I missing something obvious?
Here is the answer you're looking for:
The TIMESTAMP data type is used for values that contain both date and
time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to
'2038-01-19 03:14:07' UTC.
Source: http://dev.mysql.com/doc/refman/5.0/en/datetime.html
The date you're trying to set is to high.
I think you need to change the datatype of your column from Timestamp to Datetime as for the limitation of Timestamp to take the maximum data as '2038-01-19 03:14:07' UTC..
You need to escape the column "time" since it's a keyword in MySql.
`time`
See this answer: i can't use 'time' word in mysql query?
Related
I have a field named premium_end_date, and I run a query to retrieve a date that is smaller than premium_end_daten, the field records are stored as milliseconds:
mysql> SELECT id_prem, premium_end_date FROM ads_premium LIMIT 1;
+---------+------------------+
| id_prem | premium_end_date |
+---------+------------------+
| 1 | 1633967568 |
+---------+------------------+
1 row in set (0.00 sec)
The table looks like:
mysql> describe ads_premium;
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| id_prem | int unsigned | NO | PRI | NULL | auto_increment |
| premium_views | bigint | YES | | NULL | |
| premium_start_date | bigint | YES | | NULL | |
| premium_end_date | bigint | YES | | NULL | |
+--------------------+--------------+------+-----+---------+----------------+
10 rows in set (0.03 sec)
I run this query:
/** code here */
WHERE premium_end_date >= CURDATE()
/** code here */
But as the record is in milliseconds, it does not return anything, and I do not want to change the field from bigint to another one, as I have a lot of data inside
That looks like a straight forward unix timestamp to me.
If you run,
SELECT FROM_UNIXTIME(1633967568);
Do you get a date like 2021-10-11 15:52:48
So you can select using
WHERE FROM_UNIXTIME(premium_end_date) >= CURRENT_TIMESTAMP()
I have three column mysql table
ID (int)
Date (Varchar) (data in dd-mm-yyyy)
Logdate (Date) (Currently empty)
Is there any query which can fetch date and update the Logdate with mysql date format (yyyy-mm-dd)
You can use the STR_TO_DATE function to convert the string to a Date value. You have to specify the format of the date string you provided. In your case it would be '%d-%m-%Y'. For testing purposes you can run the following queries to check if it works:
mysql> EXPLAIN Dummy;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| ID | int(11) | YES | | NULL | |
| oldDate | varchar(50) | YES | | NULL | |
| logdate | date | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> SELECT * FROM Dummy;
+------+------------+------------+
| ID | oldDate | logdate |
+------+------------+------------+
| 1 | 24-12-2019 | 2000-01-01 |
| 1 | 04-09-2017 | 2000-01-01 |
| 1 | 21-02-2019 | 2000-01-01 |
+------+------------+------------+
3 rows in set (0.00 sec)
mysql> SELECT oldDate, STR_TO_DATE(oldDate, '%d-%m-%Y') FROM Dummy;
+------------+----------------------------------+
| oldDate | STR_TO_DATE(oldDate, '%d-%m-%Y') |
+------------+----------------------------------+
| 24-12-2019 | 2019-12-24 |
| 04-09-2017 | 2017-09-04 |
| 21-02-2019 | 2019-02-21 |
+------------+----------------------------------+
3 rows in set (0.00 sec)
You can then run an UPDATE query to update the values in the logdate column.
mysql> UPDATE Dummy SET logdate = STR_TO_DATE(oldDate, '%d-%m-%Y');
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> SELECT * FROM Dummy;
+------+------------+------------+
| ID | oldDate | logdate |
+------+------------+------------+
| 1 | 24-12-2019 | 2019-12-24 |
| 1 | 04-09-2017 | 2017-09-04 |
| 1 | 21-02-2019 | 2019-02-21 |
+------+------------+------------+
3 rows in set (0.00 sec)
You can do manual positioning from the query. Here is on example:
SELECT CONCAT_WS('-',RIGHT(date,4),MID(date,4,2),LEFT(date,2)) as Newdate FROM table;
Then with that you can construct your update query as following:
UPDATE table SET Logdate = CONCAT_WS('-',RIGHT(date,4),MID(date,4,2),LEFT(date,2));
EDITED:
I removed my first comment about STR_TO_DATE because after testing, it proved to be usable as pointed out in #Progman answer.
I need to populate a DATETIME column with the data from other columns, one for the date and one for the time.
This is part of a code I've written but I am stuck at actually combining them:
THANK YOU!
delimiter $
create trigger fulldate
before insert
on Tabela_veche
for each row
begin
if new.fulldate is null then
set new.fulldate = = CONCAT();
end if;
end $
Assuming your table looks a bit like this
+----------+----------+------+-----+---------+---------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+---------+
| dt | date | YES | | NULL | |
| tm | time | YES | | NULL | |
| fulldttm | datetime | YES | | NULL | |
| gcdttm | datetime | YES | | NULL | VIRTUAL |
+----------+----------+------+-----+---------+---------+
4 rows in set (0.02 sec)
and dt is formatted '2019-01-01' and time '10:00:00' then str_to_date
select str_to_date(concat(dt,' ',tm),'%Y-%m-%d %h:%m:%s') dttm
from t;
returns
+---------------------+
| dttm |
+---------------------+
| 2019-00-01 10:00:00 |
+---------------------+
1 row in set (0.00 sec)
As pointed out by #Raymond Nijland you may be able to use a generated column
`gcdttm` datetime AS (str_to_date(concat(dt,' ',tm) ,'%Y-%m-%d %h:%m:%s'))
and not bother with the trigger at all.
+------------+----------+----------+---------------------+
| dt | tm | fulldttm | gcdttm |
+------------+----------+----------+---------------------+
| 2019-01-01 | 10:00:00 | NULL | 2019-00-01 10:00:00 |
+------------+----------+----------+---------------------+
1 row in set (0.00 sec)
I have a table that looks like this in MySQL:
mysql> describe sale;
+-------------+------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------+------+-----+-------------------+-----------------------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| salesperson | int(11) | NO | MUL | NULL | |
| customer | int(11) | NO | MUL | NULL | |
| product | int(11) | NO | MUL | NULL | |
| count | int(11) | NO | | NULL | |
+-------------+------------+------+-----+-------------------+-----------------------------+
Now if a run this statement, I get an ERROR 1292:
mysql> insert into `sale` values (25860,'2006-04-02 02:30:50',1,25,2,21);
ERROR 1292 (22007): Incorrect datetime value: '2006-04-02 02:30:50' for column 'timestamp' at row 1
However, if I just change the date by one day, the statement works:
mysql> insert into `sale` values (25860,'2006-04-03 02:30:50',1,25,2,21);
Query OK, 1 row affected (0.00 sec)
What is the magical thing about the second of April 2006? I can't detect any problems with the format specified. I also tried retyping the statement to make sure it was not caused by invisible characters.
Daylight Saving Time.
On 2006-04-02 at 2am the clock jumped to 3am. So there was no 02:30:50
I have a dataset that I'm trying to debug a few issues on, and I've run into a case where an update query matches a record in the table, but doesn't update the data. This is my dataset:
> describe genotypes;
+--------------+------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| userstamp | int(11) | YES | | NULL | |
| timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+--------------+------------+------+-----+-------------------+-----------------------------+
12 rows in set (0.00 sec)
> SELECT id, userstamp FROM genotypes WHERE id = 7276;
+------+-----------+
| id | userstamp |
+------+-----------+
| 7276 | NULL |
+------+-----------+
When I try to run my query to update the userstamp field, I get the following result:
> UPDATE genotypes SET userstamp = 142 WHERE id = 7276;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
I've remove all my triggers from the table, so I'm not sure what's blocking the update.