MySQL STR_TO_DATE ends as a "0" (zero) - mysql

SELECT STR_TO_DATE('1.1.2000 0:00:00','%e.%c.%Y') will end up like 2000-01-01
but when I'm trying to do the same on column with values 1.1.2000 0:00:00 by running
SELECT
FirstDisplayedDate,
FirstDisplayedDate = STR_TO_DATE(FirstDisplayedDate,'%e.%c.%Y')
FROM product
I will get zero (NOT NULL!) in every row.
What am I doing wrong? :(

You get what you write: FirstDisplayedDate = STR_TO_DATE(FirstDisplayedDate,'%e.%c.%Y') compares FirstDisplayedDate with STR_TO_DATE(FirstDisplayedDate,'%e.%c.%Y') and if they are not equal returns zero. I think you want to use alias here so:
SELECT
FirstDisplayedDate,
STR_TO_DATE(FirstDisplayedDate,'%e.%c.%Y') AS FirstDisplayedDate2
FROM product

The STR_TO_DATE() function is the inverse of the DATE_FORMAT() function. It takes a string str and a format string format.
STR_TO_DATE() returns a DATETIME value if the format string contains both date and time parts, or a DATE or TIME value if the string contains only date or time parts.
If the date, time, or datetime value extracted from str is illegal, STR_TO_DATE() returns NULL and produces a warning.
The server scans str attempting to match format to it. The format string can contain literal characters and format specifiers beginning with %. Literal characters in format must match literally in str. Format specifiers in format must match a date or time part in str.
And, the reason to get zero is that unspecified date or time parts have a value of 0, so incompletely specified values in str produce a result with some or all parts set to 0, for example:
mysql> SELECT STR_TO_DATE('abc','abc');
-> '0000-00-00'
mysql> SELECT STR_TO_DATE('9','%m');
-> '0000-09-00'
mysql> SELECT STR_TO_DATE('9','%s');
-> '00:00:09'
Check in your query which format to use for date/time matching and make sure your database rows contains strings, which can be converted as dates and do not assign output values from the function to the same database field:
SELECT
FirstDisplayedDate,
STR_TO_DATE(FirstDisplayedDate,'%e.%c.%Y') AS Converted
FROM product
Here and here is more information how to use the function properly.

Related

SQL STR_TO_DATE

I'm having trouble with the following code:
INSERT into `fun` ( funner)
SELECT YEAR(STR_TO_DATE(SUBSTRING(time,1,4), '%Y'))
FROM `orig`
returning the warning:
Incorrect datetime value: '1880' for function str_to_date
time is a varchar column in the table orig with the format yyyy/mm.
I want to extract the year section from this varchar and translate it into a year datatype using STR_TO_DATE
I would recommend using one of the usual date and time MySQL datatypes, instead of the rarely used YEAR datatype : DATE, DATETIME and TIMESTAMP.
If you want to turn your string to a date datatype, then :
STR_TO_DATE(my_column, '%Y/%m')
You can use the YEAR() function on this date, and it will return an integer value :
YEAR(STR_TO_DATE(my_column, '%Y/%m'))
Finally : if all you want is get the year from a date stored as string, then you can directly extract it the string using SUBSTR :
SUBSTR(my_column, 1, 4)
This returns a string (not an integer), that MySQL will implictely convert to a number when used in numeric context.
You can convert SUBSTRING(time,1,4) to integer:
SELECT CONVERT(SUBSTRING(time,1,4),UNSIGNED INTEGER) FROM orig
there is no need to convert it first to a date and then convert to integer.
I guess you need to return an integer value since you use the YEAR() function.
If not a simple SELECT SUBSTRING(time,1,4) FROM orig will do.
What does time look like? If year has the data type year, then you can insert a date into the column:
INSERT into `clean` (year)
SELECT DATE(CONCAT(SUBSTRING(time, 1, 4), '-01-01'))
FROM `orig` ;
I am not a fan of the year data type. You should just put the entire date into the column.

How can i do a count of two columns in mysql?

i want to do a count of two columns in mysql. One of the columns is a string but another is a date like 06/08/2017 and when i do my query i get 0 results.
SELECT count(*) FROM `castigos` WHERE inicio_normal=05/06/2017 AND cod_emplazamiento=1
I have entries of that data but its dont show me anything. Maybe the type of data in the date is wrong?
What should i do?
Add the date field to your select and group by it. Otherwise mysql extensions doesn't recognize you want to group by the date and will aggregrate all the results into 1 column. And since you are getting 0 count, you're where clause must not be working.
Your date format seems malformed. usually YYYY/MM/DD format (standard format);
or specify a format using SELECT STR_TO_DATE('17/09/2010','%d/%m/%Y');
MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The supported range is '1000-01-01' to '9999-12-31'.
the below uses the implicit casting and default date format to convert the string date to a valid date.
SELECT inicio_normal, count(*)
FROM `castigos`
WHERE inicio_normal='2017/05/06'
AND cod_emplazamiento=1
GROUP BY inicio_normal
Otherwise its doing math and comparing that date to the number stored for the date.
Understand dates should be stored in a date datatype and when you query dates you're passing in a string that is being cast to a date datatype for comparison. So you need to use the standard format, or cast your string to a date so the db engine knows how to convert your format to a date.
Try this :
SELECT count(*) FROM `castigos` WHERE inicio_normal="05/06/2017" AND cod_emplazamiento=1 GROUP BY inicio_normal
WHERE inicio_normal=05/06/2017
If you divide 3 by 6 then by 2017 you get a very small value indeed. OTOH if you reformat this as a date (e.g. 20170605, if you gave us a European formatted date - dd/mm/yyyy) then your query will find the rows you showed us.

Convert varchar datatype to datetime in MySQL

How am I going to convert the time in my database which is in varchar(30) data type to datetime, I have this sample 11:45:24 09/23/2016, suppose this have to be converted into 2016-9-23 11:45:24. My column name is due_by. I have search and tried different suggestions but it seems that none of those queried successfully or correctly. I'm running it in MySQL workbench.
sample code
SELECT convert(varchar(30),'yyyy-mm-dd hh:mm:ss', 120)
FROM csbrms.user_request;
Just want my due_by format to be equal to Now() column's format.
I think we cant directly convert that into now format as it is possible in Sql Server so I have tried this if you are ok with it, please have a look.
MySQL:
SELECT
CONCAT(STR_TO_DATE(
RIGHT(TRIM(due_by), 10), '%m/%d/%Y'), ' ',
STR_TO_DATE(due_by,'%h:%i:%s')) nowFormat
FROM csbrms.user_request;
SQL Server:
SELECT CONVERT(DATETIME, '11:45:24 09/23/2016', 120)
STR_TO_DATE(str,format)
This is the inverse of the DATE_FORMAT() function. It takes a string str and a format string format. STR_TO_DATE() returns a DATETIME value if the format string contains both date and time parts, or a DATE or TIME value if the string contains only date or time parts. If the date, time, or datetime value extracted from str is illegal, STR_TO_DATE() returns NULL and produces a warning.
The server scans str attempting to match format to it. The format string can contain literal characters and format specifiers beginning with %. Literal characters in format must match literally in str. Format specifiers in format must match a date or time part in str. For the specifiers that can be used in format, see the DATE_FORMAT() function description.
mysql> SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y');
-> '2013-05-01'
mysql> SELECT STR_TO_DATE('May 1, 2013','%M %d,%Y');
-> '2013-05-01'
Scanning starts at the beginning of str and fails if format is found not to match. Extra characters at the end of str are ignored.
mysql> SELECT STR_TO_DATE('a09:30:17','a%h:%i:%s');
-> '09:30:17'
mysql> SELECT STR_TO_DATE('a09:30:17','%h:%i:%s');
-> NULL
mysql> SELECT STR_TO_DATE('09:30:17a','%h:%i:%s');
-> '09:30:17'
Unspecified date or time parts have a value of 0, so incompletely specified values in str produce a result with some or all parts set to 0:
mysql> SELECT STR_TO_DATE('abc','abc');
-> '0000-00-00'
mysql> SELECT STR_TO_DATE('9','%m');
-> '0000-09-00'
mysql> SELECT STR_TO_DATE('9','%s');
-> '00:00:09'
Range checking on the parts of date values is as described in Section 11.3.1, “The DATE, DATETIME, and TIMESTAMP Types”. This means, for example, that “zero” dates or dates with part values of 0 are permitted unless the SQL mode is set to disallow such values.
mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');
-> '0000-00-00'
mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
-> '2004-04-31'
If the NO_ZERO_DATE or NO_ZERO_IN_DATE SQL mode is enabled, zero dates or part of dates are disallowed. In that case, STR_TO_DATE() returns NULL and generates a warning.
Note :-
You cannot use format "%X%V" to convert a year-week string to a date because the combination of a year and week does not uniquely identify a year and month if the week crosses a month boundary. To convert a year-week to a date, you should also specify the weekday:
mysql> SELECT STR_TO_DATE('200442 Monday', '%X%V %W');
-> '2004-10-18'
Use the following:
DECLARE #Date varchar(8)
set #Date='10102016'
SELECT CONVERT(datetime,RIGHT(#Date,4)+LEFT(#Date,2)+SUBSTRING(#Date,3,2))
OUTPUT:
-----------------------
2016-10-10 00:00:00.000
(1 row(s) affected)
Use the below for MySQL:
SELECT STR_TO_DATE('11:44:00 10/10/2016', '%h:%m:%s %m/%d/%Y')

Convert date time string to date

MS Access Table January2015 has a txndate field with the string "2015-01-01 11:48:00"
The field type is text.
The string needs to be converted to date/time i.e. it should appear in the same format but as a time.
Running this query:
SELECT Format(datevalue(txndate), "dd-mm-yyyy hh:mm:ss") FROM January2015;
gives the output:
01-01-2015 00:00:00
(the time part is being ignored).
How can I fix this?
You can get your desired result with one Format() instead of two.
SELECT Format(CDate(txndate),"dd-mm-yyyy hh:nn:ss") AS Expr1
FROM January2015;
Actually Format() will accept your ymd date string without the need to first convert it to Date/Time, so you could eliminate CDate() if you prefer.
SELECT Format(txndate,"dd-mm-yyyy hh:nn:ss") AS Expr1
FROM January2015;
Note however the datatype of that calculated field will be text, not Date/Time because Format() always returns a string.
SELECT Format(DateValue(txndate),"dd-mm-yyyy") & " " & Format(TimeValue(txndate),"hh:nn:ss") AS Expr1
FROM January2015;

MySQL varchar timestamp column stored two different ways

I have a table with device data, one of the columns created_ts -> varchar(30)
The problem: this data in this column contains both linux timestamps and varchars for example:
1381148885
and
2012-09-17 22:13:17
How can I query this column for all records with created_ts > 2013-10-01
I'd opt for distinguishing between the string formats (either 'YYYY-MM-DD' or unix timestamp integer) by checking for a dash character.
I'd consider explicitly converting both of those formats to the DATE datatype, using an appropriate conversion. I'd compare the resulting DATE value with the date literal.
Something like this:
WHERE IF(LOCATE('-',t.created_ts,5), -- which format (yyyy-mm-dd or integer)
STR_TO_DATE(t.created_ts,'%Y-%m-%d %T'), -- convert yyyy-mm-dd string to date
FROM_UNIXTIME(t.created_ts) -- convert string as integer to date
) >= '2013-10-01' -- compare to date literal
Another option would be to convert the string column and the date literal to integer values, and do an integer comparison. (Again, two different conversions for the string column, depending on the format.)
NOTE: I included the hh:mm:ss portion in the conversion with the %T.
When no time component is supplied, the time components is assumed to be midnight (zeros) 00:00:00, and that comes into play depending on whether or not we want to consider
'2013-10-01 07:34:55' > '2013-10-01 00:00:00'
OP query has a greater than comparison. I used a greater than or equal to comparison.
This could all be adjusted, depending on the requirements. We want to be aware that if we aren't careful, some values will get "rounded down" to the previous midnight, and then when we do a greater than comparison, what we're really getting is equivalent to >= '2013-10-02'.
My preference is to make it more explicit. It makes it easier for the reader to understand what the query is actually doing.
UPDATE
I had the arguments in the LOCATE function backwards... the string to search for should be the first argument, the string to be searched is second. That's been corrected in the query above.
Something like this:
select * from yourTable
where created_ts > '2013-10-01'
or from_unixtime(created_ts) > '2013-10-01';