How to Convert returned values to decimal and SUM MySQL? - mysql

I have a number of values stored as varchar, where values are stored in the string form:
10,000,000.00
I would like to convert this number to a double to display:
10000000.00 AND then SUM it with the rest of the values of that format
As these fields don't have types there may be the case where inputted data is of the form:
10000.00 and this should be accepted as well.
How would I go about converting the unstructured numbers.
I tried:
SELECT SUM(CAST(value as DECIMAL(10,2))) FROM meta_bs
WHERE bs_id = 361
In the above case:
10000000.00 becomes 10.00
Please assist, thanks!

You can use REPLACE function to remove the commas:
SELECT SUM(CAST(REPLACE(value, ',', '') as DECIMAL(10,2)))
FROM meta_bs
WHERE bs_id = 361
Please see fiddle here.

Related

MySQL STR_TO_DATE Problem while using this function

As title, I'm trying to convert a VARCHAR column in a DATE column, and data is populated in that format "DDMMYYYY" ex. XMAS is "25122022" and in this case the correct formula should be STR_TO_DATE(column, '%d%m%Y')Well, when I execute this query I get an error since in some cases I have values with a "missing" char, I mean, for example, "1012023" when the day is <10 the query fails, cause it checks for "01122023" instead.I could solve this easily by adding a 0 to all fields having length 7, but I'd like to make it more clean.Reading better the usage of STR_TO_DATE I noticed that I could replace %d with %e since the second choice should theorically consider days from 0 to 31 instead of 01 to 31.Unexpectedly the query didn't work and gave me the same erorr at the first instance of a length 7 string.Am I doing something wrong?Thanks in advance.
We can try left padding your date string with zero to a length of 8:
WITH yourTable AS (
SELECT '1012023' AS dt
)
SELECT STR_TO_DATE(LPAD(dt, 8, '0'), '%d%m%Y') AS dt_out -- 2023-01-01
FROM yourTable;
Demo

Postgresql json field has dates in both YYYY-MM-DD and 13 digit unix timestamp format

I am parsing a json array and one field I am pulling out is closedate. However closedate has two different date formats one is YYYY-MM-DD and the other is a 13 digit timestamp. I am trying to get consistent formatting of the dates as well as have it be an integer compared to a string. Right now the query returning the close date is:
json_array_elements(ld.data->'Table1'->'Details')->>'closeDate' as closedate
and it returns close date as a string:
id
closedate
1
2021-09-29
2
1606824000000
Someone was telling me to do something like a case statement with regex. But I am not familiar with regex function. Any help is appreciated.
Edit: I have
case when x.closedate::text ~* '^[0-9]{13}$' then
to_timestamp(x.closedate::bigint/1000)
when x.closedate = '0' then null
when x.closedate = '' then null
else
to_date(x.closedate,'MMDDYYYY') end as transactionclosedate
the case statement works for converting the 13 digit timestamp to a date but I am getting the error:
ERROR: date/time field value out of range: "2020-10-23"
when trying to convert the date strings in the correct format to dates in the else part of the case statement.
An example of one way to make this work. My regex skills are not strong so others may have a better solution:
create table regex_test (id int, fld_1 varchar);
insert into regex_test values (1, '1606824000000'), (2, '2021-09-29');
select * from regex_test ;
id | fld_1
----+---------------
1 | 1606824000000
2 | 2021-09-29
select
id,
case when fld_1 ~* '^[0-9]*$' then
to_timestamp(fld_1::bigint/1000)
else
fld_1::timestamp end as ts_fld
from
regex_test;
id | ts_fld
----+------------------------
1 | 2020-12-01 04:00:00-08
2 | 2021-09-29 00:00:00-07
I hope this query help you
with data as (
select
json_array_elements(data->'Table1'->'Details')->>'closeDate' as closedate
from your_table
)
select
case when closedate::text ~ '^[0-9]+$' then
to_timestamp(closedate::numeric / 1000)::date
else
closedate::date
end
from data;
Either of the other answers would be ok providing that only the specified formats exist. However, containing those formats requires a text field; which may contain anything. It is dangerous to assume if the content is not 13 digits then it is a valid formatted ISO date. I would validate that as well (and verify digits length).
select id,
, case when closedate ~* '^[0-9]{13}$' then
to_timestamp(closedate::bigint/1000)
when is_valid_iso_date(closedate) then
closedate::timestamp
else
'-infinity'::timestamp -- or whatever to indicate Invalid Date.
from <your table> ;
The problem being that is_valid_iso_date function. It turns out however I had to create just that a couple years ago, I'll make the result available here.
DISCLAIMER: While the function has given no known erroneous results it has NOT been exhaustively tested.

How to convert formatted string like "120k" to integer/double in Mysql

Sometimes we got raw data of number is imported in a human readable string format, e.g. "955.37K". In Mysql, is there any built-in method to convert it back to computable types, e.g. 955370.0 ?
You could use a CASE expression with the help of regex substring logic:
SELECT
data,
CASE REGEXP_SUBSTR(data, '[A-Z]$')
WHEN 'K' THEN 1000
WHEN 'M' THEN 1000000
WHEN 'B' THEN 1000000000
ELSE 1 END *
CAST(REGEXP_SUBSTR(data, '^\\d+(\\.\\d+)?') AS UNSIGNED) AS full_data
FROM yourTable;
Demo

How to assign number data type to new column using SQL SELECT

I am generating a query table using SQL SELECT as below. This formats the numbers in the column 'Free Cashflow (USD mm)' with 2 digits, but the resulting column data type is 'text'.
How can I instead assign a number data type, e.g. 'float' with 2 digits, to the new column 'Free Cashflow (USD mm)' ?
SELECT
(format(("fcf" / "fxusd") / 1000000, 2) as 'Free Cashflow (USD mm)'
FROM "SF1"
You can CAST it to DECIMAL. Note that for values >= 1000, FORMAT will insert a , in the result, which will prevent the CAST from working correctly. Since FORMAT effectively just ROUNDs the value to the given number of decimal places, you can use ROUND instead to resolve that problem:
SELECT
CAST(ROUND(("fcf" / "fxusd") / 1000000, 2) AS DECIMAL(9,2)) as 'Free Cashflow (USD mm)'
FROM "SF1"
Demo on dbfiddle

Issue with casting String to decimal in MySQL

I have a column in a data set that contains a currency indicator and the corresponding amount of that currency (i.e USD 35,000.05). I am trying to get the substring of the column containing the number and convert it to a decimal. However, whenever I convert it, it only returns the first two digits of the number I am trying to get.
For example, this is what happens:
In this sample, this is my query:
SELECT
SUBSTRING(`Annualized Opportunity Amount`,1,3) as `test1`,
(SUBSTRING(`Annualized Opportunity Amount`,5)) as test2,
case when SUBSTRING(`Annualized Opportunity Amount`,1,3) = 'AUD'
then CAST(SUBSTRING(`Annualized Opportunity Amount`,5) AS DECIMAL(10,2))
else 0 END as `test3`
from annualized_opportunity_revenue
Is there any reason as to why only the first 2 digits of the test2 column would be returned in test3? The substrings for the resulting value are the same so I don't understand why casting it would alter the data.
Any help will be appreciated, thank you.
You must remove the comma from the string before casting it to a number:
CAST(SUBSTRING(REPLACE(`Annualized Opportunity Amount`,',',''),5) AS DECIMAL(10,2))