I am trying to read a file to mysql database, there is time column format like this
05/20/16 01:54:52.797 AM => month/day/year hours:minutes:seconds.millisecond AM/PM
I am using the following code by I can't read it corrrectly
Drop table temp;
CREATE TABLE temp LIKE messages;
load data infile 'C:/xampp/htdocs/gdxg/test_uploads/test.txt' into table temp fields terminated by '\t' enclosed by '"' lines terminated by '\n' (#Time, State, Name,Pri,Value,)
SET Time = STR_TO_DATE(#Time,'%m/%d/%y %H:%i:%s.%f');
select * from temp limit 10;
It doesn't read AM/PM
and if I tried to do so (#Time,'%m/%d/%y %H:%i:%s.%f %p) just read null?
You have used hour specifier wrongly.
Specifier descriptions:
'%H' - for hours in range (00..23)
'%h' - for hours in range (01..12)
'%p' - for AM or PM
Change H to h in your query and use of '%p' should be working.
Example:
mysql> select #t;
+--------------------------+
| #t |
+--------------------------+
| 05/20/16 01:54:52.797 AM |
+--------------------------+
1 row in set (0.00 sec)
mysql> select STR_TO_DATE( #t,'%m/%d/%y %h:%i:%s.%f %p' ) as t;
+----------------------------+
| t |
+----------------------------+
| 2016-05-20 01:54:52.797000 |
+----------------------------+
1 row in set (0.00 sec)
Read Documentation:
DATE_FORMAT(date,format)
Related
I've a column in a table (varchar) with dates in this format
2013-09-05T10:10:02Z
How do I convert this into datetime format and save it in another column, using an update query?
You can use the STR_TO_DATE function:
UPDATE table1 SET col2 = STR_TO_DATE(col1,'%Y-%m-%dT%TZ')
Example:
mysql> select STR_TO_DATE('2013-09-05T10:10:02Z','%Y-%m-%dT%TZ');
+----------------------------------------------------+
| STR_TO_DATE('2013-09-05T10:10:02Z','%Y-%m-%dT%TZ') |
+----------------------------------------------------+
| 2013-09-05 10:10:02 |
+----------------------------------------------------+
1 row in set (0.00 sec)
You can also use CAST('2013-09-05T10:10:02Z' AS DATETIME) which does not require a format definition as in STR_TO_DATE().
If you want to take care of the timezone just use this query, and use the mysql timezone
mysql> select CONVERT_TZ("2013-09-05T10:10:02Z", "+00:00", ##session.time_zone);
+-------------------------------------------------------------------+
| CONVERT_TZ("2013-09-05T10:10:02Z", "+00:00", ##session.time_zone) |
+-------------------------------------------------------------------+
| 2013-09-05 12:10:02 |
+-------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
or any other timezone
mysql> select CONVERT_TZ("2013-09-05T10:10:02Z", "+00:00", "+03:00");
+--------------------------------------------------------+
| CONVERT_TZ("2013-09-05T10:10:02Z", "+00:00", "+03:00") |
+--------------------------------------------------------+
| 2013-09-05 13:10:02 |
+--------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
I tried using the cast method from above but would get the truncated error as describe in the comments.
You can also use CAST('2013-09-05T10:10:02Z' AS DATETIME) which does not require a format definition as in STR_TO_DATE().
I would consistently get: Error: Truncated incorrect datetime value: '2011-10-02T23:25:42Z'
I fixed it by casting the value to an # variable before using it in my query. Here is an example in a Stored Procedure:
CREATE PROCEDURE `new_procedure`(IN p_date VARCHAR(50), p_text VARCHAR(500))
BEGIN
SET #datestring = CAST(p_date AS DATETIME);
-- used for debugging
SELECT #datestring, p_text;
INSERT INTO testtable(timestamp, text) VALUES(#datestring, p_text);
END
I am running the following query on my wordpress website
$error = $wpdb->update( $table_name,
array( 'value' => $update_value ),
array( 'lead_id' => $lead_id,
'field_number' => 31.3 ),
array( '%s' ),
array( '%d', '%f' )
);
It is intended to update gravity form entries after the user has initially submitted the form. This query runs fine for 24 fields but returns 0 for 2.
I have so far tried the following troubleshooting steps:
Storing the result as $error and running var_dump($error); after the query, it returns 0.
Running var_dump( $wpdb->last_query ); immediately after the query to copy/paste the resulting SQL string into phpMyAdmin, which also reports 0 rows affected.
Manually selecting the row in phpMyAdmin using:
SELECT * FROM `table_name` WHERE `field_number` = 31.3
Which also returns no rows. However, I know that there are rows which match as I can se them in the table.
Manually selecting another field which updates as expected using the same query as above - this worked fine.
Changed the $where_format from float to string. No resulting change. Upon checking the db fields, the field_number field is stored as a float.
Used $wpdb->prepare to run a prepared query. Still no movement.
Prepare statement as follows:
$error = $wpdb->query(
$wpdb->prepare(
"
UPDATE %s
SET value = %s
WHERE lead_id = %d AND field_number = %f
",
$table_name, $update_value, $lead_id, 31.3
)
);
Which, when var_dumped gives the following result:
string '
UPDATE prefix_rg_lead_detail
SET `value` = 'a:3:{i:0;s:9:\"Liverpool\";i:1;s:10:\"Manchester\";i:2;s:5:\"Leeds\";}'
WHERE `lead_id` = 4 AND `field_number` = 31.300000
' (length=188)
I'm at my wits end now as I've tried everything I can possibly think of and still cant get 2 fields to update.
Your final problem is indeed with the FLOAT type. It is an imprecise value, which is leading you to your problem. Although the database is showing the value 31.3 it most likely internally in the database is something like 31.30000000000001 which is why the where condition is not working. Take a look at the documentation here: Problems with Floating-Point Values.
So down the road lets go to the tests:
create table test (
n float
);
insert into test values (31.3);
mysql> select * from test;
+------+
| n |
+------+
| 31.3 |
+------+
1 row in set (0.17 sec)
Running a select statement on it with that value 31.3 will evaluate to nothing:
mysql> select * from test where n=31.3;
Empty set (0.00 sec)
There are a few ways you can solve it without changing the column type:
1- Using the ROUND(field,number_of_decimals) function
mysql> select * from test where round(n,2)=31.3;
+------+
| n |
+------+
| 31.3 |
+------+
1 row in set (0.00 sec)
2- Casting it as DECIMAL type
mysql> select * from test where cast(n as decimal(5,2))=31.3;
+------+
| n |
+------+
| 31.3 |
+------+
1 row in set (0.00 sec)
So in order to your update to work with this data you have to use one of those options in your update command like:
$wpdb->query( $wpdb->prepare("UPDATE %s
SET value = %s
WHERE lead_id = %d
AND round(field_number,2) = %f ",
$table_name,
$update_value,
$lead_id,
31.3 )
);
My recommendation is that you change the field type. AFAIK there is no situation where your plugin may break as of this change. What it may happens is a rounding value like you try to insert a value like 31.696 in a Decimal field of (6,2) it will became 31.67. Also the difference is that the value of the field will be formatted as the decimals number you chose so 31.3 will start to apear as 31.30 You can change it as:
alter table yourTableName modify field_name DECIMAL(6,2);
Here are some test on that explanation:
mysql> alter table test modify column n decimal(10,2);
Query OK, 1 row affected, 1 warning (0.90 sec)
Records: 1 Duplicates: 0 Warnings: 1
mysql> select * from test;
+-------+
| n |
+-------+
| 31.30 |
+-------+
1 row in set (0.00 sec)
mysql> select * from test where n=31.3;
+-------+
| n |
+-------+
| 31.30 |
+-------+
1 row in set (0.00 sec)
And to show the rounding:
mysql> insert into test values (31.696);
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> select * from test;
+-------+
| n |
+-------+
| 31.30 |
| 31.67 |
+-------+
2 rows in set (0.01 sec)
can someone help me with this, my resulting table is showing only zeros for the timestamp. I tried changing the field type to datatime and timestamp but not luck
MYSQL
LOAD DATA LOCAL INFILE 'vals.csv'
INTO TABLE vals
FIELDS TERMINATED BY ","
LINES TERMINATED BY "\n"
IGNORE 1 LINES
(#varTimeSt,NOMINAL,NAME,ID,VAL) SET DATETIME = STR_TO_DATE(#varTimeSt,'%d/%m/%Y %h:%i:%s');
CSV File
DATETIME,NAME,ID,VAL
"25/08/2016 02:00:00",tom,cNum6,12
"25/08/2016 02:00:00",Charles,cNum7,10.58
"25/08/2016 02:00:00",Donal,cNum8,10.18
"25/08/2016 02:00:00",Duncan,cNum7,10.31
Resulting table
DATETIME,NAME,ID,VAL
0000-00-00 00:00:00,tom,cNum6,12
0000-00-00 00:00:00,Charles,cNum7,10.58
0000-00-00 00:00:00,Donal,cNum8,10.18
0000-00-00 00:00:00,Duncan,cNum7,10.31
Your problem is that your dates are not in native mysql DATETIME format (%Y-%m-%d %H:%i:%s), this can be shown as such:
mysql> SELECT CAST('25/08/2016 02:00:00' AS DATETIME);
+-----------------------------------------+
| CAST('25/08/2016 02:00:00' AS DATETIME) |
+-----------------------------------------+
| NULL |
+-----------------------------------------+
1 row in set, 1 warning (0,00 sec)
mysql> SHOW WARNINGS;
+---------+------+-------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------+
| Warning | 1292 | Incorrect datetime value: '25/08/2016 02:00:00' |
+---------+------+-------------------------------------------------+
1 row in set (0,00 sec)
The solution is to get them into MySQL format, this could be done by manipulating your DATETIME column on disk or at source. This may be more difficult than the 'self sufficient' solution I'll outline below.
There exists the string to date (STR_TO_DATE) function to solve this kind of issue once data is inside the database, here is a demonstration with your format. Otherwise see the manual here. (See the DATE_FORMAT section for a table with the codes you can use for different date formats.):
mysql> SELECT CAST(STR_TO_DATE('25/08/2016 02:00:00', '%d/%m/%Y %H:%i:%s') AS DATETIME);
+---------------------------------------------------------------------------+
| CAST(STR_TO_DATE('25/08/2016 02:00:00', '%d/%m/%Y %H:%i:%s') AS DATETIME) |
+---------------------------------------------------------------------------+
| 2016-08-25 02:00:00 |
+---------------------------------------------------------------------------+
1 row in set (0,00 sec)
Personally in this situation I'd load the data into a temporary table that accepted the date fields as a string and then use an INSERT with the STR_TO_DATEfunction to get the data into the final table. A final solution (untested, guideline only) would look like this:
CREATE TEMPORARY TABLE valsLoad (DATETIME TEXT,NAME TEXT,ID TEXT,VAL INT);
LOAD DATA LOCAL INFILE 'vals.csv'
INTO TABLE valsLoad
FIELDS TERMINATED BY ","
LINES TERMINATED BY "\n"
IGNORE 1 LINES
(#varTimeSt,NOMINAL,NAME,ID,VAL) SET DATETIME = STR_TO_DATE(#varTimeSt,'%d/%m/%Y %h:%i:%s');
INSERT INTO vals
SELECT STR_TO_DATE(DATETIME, '%d/%m/%Y %H:%i:%m'), NAME, ID, VAL FROM valsLoad;
DROP TEMPORARY TABLE valsLoad;
Please let me know if you have any questions.
Regards,
James
I've a column in a table (varchar) with dates in this format
2013-09-05T10:10:02Z
How do I convert this into datetime format and save it in another column, using an update query?
You can use the STR_TO_DATE function:
UPDATE table1 SET col2 = STR_TO_DATE(col1,'%Y-%m-%dT%TZ')
Example:
mysql> select STR_TO_DATE('2013-09-05T10:10:02Z','%Y-%m-%dT%TZ');
+----------------------------------------------------+
| STR_TO_DATE('2013-09-05T10:10:02Z','%Y-%m-%dT%TZ') |
+----------------------------------------------------+
| 2013-09-05 10:10:02 |
+----------------------------------------------------+
1 row in set (0.00 sec)
You can also use CAST('2013-09-05T10:10:02Z' AS DATETIME) which does not require a format definition as in STR_TO_DATE().
If you want to take care of the timezone just use this query, and use the mysql timezone
mysql> select CONVERT_TZ("2013-09-05T10:10:02Z", "+00:00", ##session.time_zone);
+-------------------------------------------------------------------+
| CONVERT_TZ("2013-09-05T10:10:02Z", "+00:00", ##session.time_zone) |
+-------------------------------------------------------------------+
| 2013-09-05 12:10:02 |
+-------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
or any other timezone
mysql> select CONVERT_TZ("2013-09-05T10:10:02Z", "+00:00", "+03:00");
+--------------------------------------------------------+
| CONVERT_TZ("2013-09-05T10:10:02Z", "+00:00", "+03:00") |
+--------------------------------------------------------+
| 2013-09-05 13:10:02 |
+--------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
I tried using the cast method from above but would get the truncated error as describe in the comments.
You can also use CAST('2013-09-05T10:10:02Z' AS DATETIME) which does not require a format definition as in STR_TO_DATE().
I would consistently get: Error: Truncated incorrect datetime value: '2011-10-02T23:25:42Z'
I fixed it by casting the value to an # variable before using it in my query. Here is an example in a Stored Procedure:
CREATE PROCEDURE `new_procedure`(IN p_date VARCHAR(50), p_text VARCHAR(500))
BEGIN
SET #datestring = CAST(p_date AS DATETIME);
-- used for debugging
SELECT #datestring, p_text;
INSERT INTO testtable(timestamp, text) VALUES(#datestring, p_text);
END
Here's a simple version of the table users:
+--------------+-------------------+
| id | timezone |
+--------------+-------------------+
| 1 | 'Europe/Helsinki' |
| 2 | 'Europe/Paris' |
+--------------+-------------------+
I want to know what's the local time for each one of these users (depending on their time zones), so that I can select users for who it's 4pm for example.
I'm using the LAMP stack, but I'd like to do that using MySQL only (not selecting all users and running them in a PHP loop).
Use the CONVERT_TZ for this:
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_convert-tz
SELECT * FROM users WHERE hour(CONVERT_TZ(now(), server_tz, `timezone`))=16
You can change the timezone with set time_zone:
mysql> set time_zone='Europe/Helsinki';
mysql> select now();
2012-09-21 16:15:06
mysql> set time_zone='Europe/Paris';
mysql> select now();
2012-09-21 15:15:40
Using this you can, for example, define a function that returns the current time for the user's timezone:
create function current_time_in_tz(tz varchar(40)) returns datetime
begin
set #old_tz = ##session.time_zone;
set time_zone=tz;
set #now = now();
set time_zone=#old_tz;
return #now;
end
select id, current_time_in_tz(timezone) from users;
Note that DATE, TIME and DATETIME values don't depend on the time zone, so values from columns of these types are not automatically adjusted when querying. TIMESTAMP values are adjusted:
mysql> create temporary table tbl (dt datetime, ts timestamp);
mysql> insert into tbl values (now(),now());
mysql> select * from tbl;
+---------------------+---------------------+
| dt | ts |
+---------------------+---------------------+
| 2012-09-21 15:21:56 | 2012-09-21 15:21:56 |
+---------------------+---------------------+
mysql> set time_zone='Europe/Helsinki';
mysql> select * from tbl;
+---------------------+---------------------+
| dt | ts |
+---------------------+---------------------+
| 2012-09-21 15:21:56 | 2012-09-21 16:21:56 |
+---------------------+---------------------+
If set time_zone fails with this error:
ERROR 1298 (HY000): Unknown or incorrect time zone: 'Europe/Helsinki'
you need to load the time zone info into mysql with a command like this:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
For more info see http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
A more generic (not depending on the timezone of the server) solution than Nin's answer would be:
SELECT * FROM users WHERE hour( CONVERT_TZ(UTC_TIMESTAMP(), 'UTC', timezone) )=16
It would be nice if MySQL had a function like NOW_TZ(timezone).