MySQL - VARCHAR to DATE returns null - mysql

Using Local Storage Connection within Toad Data Point. It's set up to use MYSQL.
EXTRACT_DATE is varchar(20) in the format of: 08282020
Trying to change that format so it appears as 08/28/2020 in my results set. However, I kept getting {null} returned.
I've tried a variety of different methods (see the code below) but keep getting the same result.
SELECT
EXTRACT_DATE,
DATE_FORMAT(EXTRACT_DATE, '%m/%d/%Y') AS NEW_DT,
STR_TO_DATE(EXTRACT_DATE, '%m/%d/%Y') AS NEW_DT2,
CONVERT (EXTRACT_DATE, DATE) AS NEW_DT3
FROM USERTABLE
GROUP BY EXTRACT_DATE

STR_TO_DATE turns a string into a date. To format the result, apply DATE_FORMAT like so:
select DATE_FORMAT( STR_TO_DATE('08282020', '%m%d%Y'),'%m/%d/%Y') AS NEW_DT from dual

It think it is simpler and more efficient to use sring functions:
concat_ws(
'/',
substring(extract_date, 1, 2),
substring(extract_date, 3, 2),
substring(extract_date, 5, 4)
) as new_dt
Or:
concat_ws(
'/',
left(extract_date, 2),
substring(extract_date, 3, 2),
right(extract_date, 4)
) as new_dt
As for the query you wanted to write: you need to convert to a date first, then back to a string. So:
date_format(str_to_date(extract_date, '%m%d%Y'), '%m/%d/%Y')

Related

SQL use FORMAT() on a SUM()

I want to use FORMAT on SUM to produce a currency style format with commas and no decimal places. I'm trying the following using MySQL 5.7:
SELECT FORMAT(SUM(x.07_17 / fx.07_17), 0) AS total.....
The problem is this changes the data drastically. Without the format, I get the correct result of SUM 350914 but with the format, in place, I get 350, so just the first 3 numbers.
What is it I'm doing wrong?
You can check the documentation to see how each parameters works for the FORMAT function https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_format
This query shows you different style to display your data (Sql fiddle example)
SELECT SUM(c1 / c2) AS total1
, CONCAT(FORMAT(SUM(c1 / c2), 3, 'fr_FR'), ' €') AS total2
, CONCAT('$', FORMAT(SUM(c1 / c2), 3)) total3
FROM ( SELECT 148277 c1
, 5.1561 c2 ) t

How to use SQL to sort a column by the first group of digits that appears in each row?

Is there a way to use SQL to sort a column by the first group of digits that appears in the column?
For example, the column contains values like so:
PPP-26-8
PPP-29-8
PPP-216-8
PPP-220
PPP-236
Only the first group of digits is to be considered for sorting in increasing numerical order, i.e. 26, 29, 216, 220, 236
I currently have something like this, which kind of works, but gives me warnings:
CAST(RIGHT(model, LENGTH(model) - 4) as UNSIGNED) ASC
Warning, specifically is this:
Warning | 1292 | Truncated incorrect INTEGER value: '216-8'
Update
It seems like this will do it, where - is the delimiter:
CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(model, '-', 2), '-', -1) as UNSIGNED) ASC
You could use string function to get string after first - and * 1 for type casting
select *
from demo
order by substring_index(substring_index(col,'-',2),'-',-1) * 1
demo
Assuming you always mean the second group (as defined by the "-"), then you can use substring_index(). If they always begin with "P-", you can do:
order by length(substring_index(model, '-', 2)),
substring_index(model, '-', 2)
If the initial part can be of variable length, go fo:
order by substring_index(substring_index(model, '-', 2), '-', -1) + 0
The + 0 converts the value to a number, for ordering purposes. The use + 0 for conversion uses silent conversion in MySQL. That is, it does not generate an error when the string is non-numeric. Instead, it just treats such strings as a value of "0".
You can try this:
SELECT ...
FROM MyTable
ORDER BY SUBSTRING_INDEX(SUBSTRING_INDEX(model, '-', 2), '-', -1);
If you want this to use an index, you'll have to create a virtual column and an index on the virtual column (this works in MySQL 5.7 and later).
ALTER TABLE MyTable
ADD COLUMN model_second_number AS (SUBSTRING_INDEX(SUBSTRING_INDEX(model, '-', 2), '-', -1)+0),
ADD KEY (model_second_number);
Then you have an opportunity to sort by that index:
SELECT ...
FROM MyTable
ORDER BY model_second_number;

Mysql - Multiple incorrect date format stored

I am working with data where the developer prior to me has been lazy and not stored the date in a set format. Its in as varchar and not a datetime. Needless to say its left me needing to sort the data.
Its in two formats
1) {dd}/{mm}/{yyyy} {hh}:{mm}
2) {dd}.{mm}.{yyyy} {hh}:{mm}
I would like to ensure that it is always returned in the mysql dateformat. The query below will get the first one.
SELECT
str_to_date( a.rentalstart, '%d/%m/%Y %k:%i' ),
a.*
FROM
jupiter1.table a
ORDER by createtime DESC
How would I combine the two? I would also need it default to a normal mysql datetime if it matches.
{yyyy}-{mm}-{dd} {hh}:{mm}:{ss}
SELECT CASE WHEN a.rentalstart LIKE "%/%/% %:%"
THEN str_to_date( a.rentalstart, '%d/%m/%Y %k:%i' )
WHEN a.rentalstart LIKE "%.%.% %:%"
THEN str_to_date( a.rentalstart, '%d.%m.%Y %k:%i' )
ELSE CAST(a.rentalstart AS DATETIME)
END AS rentalstart_good,
a.*
FROM ...
You can simple do REPLACE. It will turn all records in the format {dd}.{mm}.{yyyy} {hh}:{mm} and convert it to DateTime data type.
SELECT STR_TO_DATE(REPLACE(a.rentalstart, '/', '.'), '%d.%m.%Y %k:%i') newDate,
a.*
FROM jupiter1.table a
ORDER BY newDate DESC
SELECT
str_to_date( replace(replace(a.rentalstart, '.', '-'), '/', '-'), if(a.rentalstart like '%-%-%-%', '%Y-%m-%d %k:%i', '%d-%m-%Y %k:%i' )),
a.*
FROM
jupiter1.table a
ORDER by createtime DESC
Does this solve your problem?
Edited to include your default condition also

How does one construct a query that only returns this months rows, based on Timestamp?

I'm curious what the right way is to construct a query where the rows are pulled based on a timestamp that represents a specific month. Given that different months have different numbers of days, is there a way to generate a query that always gives you the rows where the timestamp contains the current month so that the results would only include the current month?
Do you mean something like this
SELECT * FROM tbl WHERE
MONTH(timesp) = MONTH(NOW()) AND
YEAR(timesp) = YEAR(NOW());
You can use the FROM_UNIXTIME() function:
SELECT *
FROM tableName
WHERE MONTH(FROM_UNIXTIME(timestampField))==6
Just use MONTH:
select *
from foo
where month_column = MONTH(getdate())
and year_column = YEAR(getdate())
Try this sql.
select *
from yourtable
where yourdatefield>=DATE_SUB(CURDATE(),INTERVAL 1 MONTH);
You're looking for something like this:
SELECT * FROM table where MONTH(date_row) = $month;
If you have an index on your date field, then this is efficient (T-SQL syntax, the idea applieas to any RDBMS though)
SELECT
*
FROM
tableName
WHERE
dateTimeField
BETWEEN
-- build the string 'YYYY-MM-01', cast back as a datetime
CAST(
CAST(YEAR(GETDATE()) AS varchar) + '-' + CAST(MONTH(GETDATE()) AS varchar) + '-01'
AS datetime
)
AND
-- add one month, subtract one day
DATEADD(mm, 1,
-- build the string 'YYYY-MM-01', cast back as a datetime
CAST(
CAST(YEAR(GETDATE()) AS varchar) + '-' + CAST(MONTH(GETDATE()) AS varchar) + '-01'
AS datetime
)
) - 1
Of course any other method to get two datetime values in the right range would work.
SQL Server has LEFT(CONVERT(varchar, GETDATE(), 120), 8) + '01' to convert a datetime to string, other Db servers have their own functions to do the same. Maybe you can calculate the two values in the calling application more easily - how you get them, is not the point.
The point is that BETWEEN can use an index, whereas the other solutions that work with WHERE MONTH(dateTimeField) = 6 will trigger a table scan, which is about the slowest operation you can do on a table.

how to join 2 separate text to one - selected from string - IN MySQL

I have date in string like "01.02.2012" like "DD.MM.YYYY" and I need it convert to DATE or string like "YYYY-MM-DD".
I try:
SELECT SUBSTRING( txtdate, 7, 4 ) AS `year` , SUBSTRING( txtdate, 4, 2 ) AS `month` ,
SUBSTRING(txtdate, 1, 2 ) AS `day`
FROM info
So I get the year, month and day and now I want to join the texts to one.
I try this just after
SELECT CONCAT_WS('-',year,month,day);
but I get an error ..
You can't refer to aliased fields elsewhere in a field definition list, unfortunately.
SELECT x AS a, CONCAT(y, a)
doesn't work. You'd have to use
SELECT CONCAT_WS('-', SUBSTRING(txtdate, 7, 4), SUBSTRING(...), SUBSTRING(...))
or, if you'd stored that date in a proper DATE field in the database, it'd a simple matter of
SELECT DATE_FORMAT('%Y-%m-%d', datefield)