MySQL format number with unknown number of decimal places - mysql

In MySQL, I only want to add thousand separator in the number like 1234.23234, 242343.345345464, 232423.22 and format to "1,234.23234", "242,343.345345464", "232,423.22", use format function need to specify the number of decimals, is there any other function can format the number with unknown number of decimal places? for 1234.23234, I do not want to get the result like 1234.2323400000 or 1234.23, just want to get 1,234.23234.

As suggested split the string drop the trailing zeros format the number before the decimal point and concat taking into account the possibility of no decimals being present at all for example
set #a = 1234.56;
select
case when instr(#a,'.') > 0 then
concat(
format(substring_index(#a,'.',1),'###,###,###'),
'.',
trim(trailing '0' from substring_index(#a,'.',-1))
)
else
format (#a,'###,###,###')
end formatted

MySQL doesn't seem to have such feature. You'll probably need to write a custom function based on FORMAT() plus some string manipulation to remove trailing zeroes after the comma, for example using REGEXP_REPLACE(). The default locale used in FORMAT() is en_US, which seems to be the one you want, so you can omit it or provide your own should you need a different locale.
WITH sample_data (sample_number) AS (
SELECT NULL
UNION ALL SELECT 0
UNION ALL SELECT 0.00001
UNION ALL SELECT 100.01
UNION ALL SELECT 100.0102
UNION ALL SELECT 100.012300456
UNION ALL SELECT 1000
UNION ALL SELECT 123456789.87654321
UNION ALL SELECT -56500.333
)
SELECT
sample_number,
REGEXP_REPLACE(
FORMAT(sample_number, 999),
'(\.\\d*[1-9])(0+$)|(\.0+$)',
'$1'
) AS USA,
-- Replace \. with , for locales that use comma as decimal separator:
REGEXP_REPLACE(
FORMAT(sample_number, 999, 'de_DE'),
'(,\\d*[1-9])(0+$)|(,0+$)',
'$1'
) AS Germany
FROM sample_data;
sample_number
USA
Germany
NULL
NULL
NULL
0.000000000
0
0
0.000010000
0.00001
0,00001
100.010000000
100.01
100,01
100.010200000
100.0102
100,0102
100.012300456
100.012300456
100,012300456
1000.000000000
1,000
1.000
123456789.876543210
123,456,789.87654321
123.456.789,87654321
-56500.333000000
-56,500.333
-56.500,333
Fiddle

Related

sql extract only numeric value from column

I have a column called' memo_line_2',the value format is like :'$3000.00 (card limit increase)',how can I only extract numeric value from the column?Thanks
example:
'$3000.00 (card limit increase)' -> 3000
'$5000.00 (card limit increase)' -> 5000
'$12000.00 (card limit increase)' ->12000
You could use REGEXP_SUBSTR() for this:
SELECT REGEXP_SUBSTR(tmp.`value`, '[0-9]+') as `new_value`
FROM (SELECT '$3000.00' as `value` UNION ALL
SELECT '$5000.00' as `value` UNION ALL
SELECT '$12000.00' as `value`) tmp
Returns:
new_value
---------
3000
5000
12000
If you would like to keep everything after the decimal, use '[0-9.]+' as your regular expression filter.
If your data will be always in this format you can use below query to select the data between $ and . :
SELECT substring_index(substring_index(memo_line_2, '$', -1), '.', 1)
FROM your_table;
Refrence: MySQL substring between two strings
You can use:
select regexp_substr(col, '[0-9]+[.]?[0-9]*')
This will extract the digits with the cents. You can then convert to an integer or numeric:
select cast(regexp_substr(col, '[0-9]+[.]?[0-9]*') as unsigned)
It can be done by making a custom function in your sql query
Take a look at:
https://stackoverflow.com/a/37269038/16536522

Remove trailing zeros only from int numbers

I have decimal column in db and trying to remove trailing zeros only from int numbers (100, 200, 300) with query in php. I tried with trim/cast functions but 10.50 turned 10.5.
SELECT TRIM(TRAILING '0' FROM `my_column`) FROM `mytable`
200.00
10.50
247.09
would display as
200
10.50
247.09
Use a case expression to determine if a number is an integer using ceil() and if it is format with zero decimals, if not with 2 decimals.
SELECT
CASE WHEN ceil(n) = n THEN format(n, 0) ELSE format(n, 2) END
FROM (
SELECT
1234.5 AS n
UNION ALL
SELECT
1234
) d

Adding another value below the row

Hey guys i have did some coding in mysql to add a new line value to a row..
SELECT
babe
FROM
(SELECT
concat_ws(' ', 'assword \n') AS babe,
) test;
When i did like this i get an output like
BABE
assword name
What i need is an output like
BABE
assword
name(this would be below assword)
Is there any mysql functions to do this ??...or can i UPDATE the row ??..
I am a newbie in mysql. Hope you guys can help me out..Thanks in advance..
The statement includes a newline character in the babe column. You can confirm this by using the HEX() function to view the character encodings.
For example:
SELECT HEX(t.babe)
FROM ( SELECT CONCAT_WS(' ', 'assword \n') AS babe ) t
On my system, that Will output:
617373776F7264200A
It's easy enough to understand what was returned
a s s w o r d \n
61 73 73 77 6F 72 64 20 0A
(In the original query, there's an extraneous comma that will prevent the statement from running. Perhaps there was another expression in the SELECT list of the inline view, and that was returning the 'name' value that's shown in the example output. But we don't see any reference to that in the outer query.
It's not clear why you need the newline character. If you want to return:
BABE
-----------
asssword
name
That looks like two separate rows to me. But it's valid (but peculiar) to do this:
SELECT t.babe
FROM ( SELECT CONCAT_WS(' ', 'assword \nname') AS babe ) t
FOLLOWUP
Q: i just wanted to know how to add a new row below the assword ..if u know please edit the answer
It's not clear what result you are trying to achieve. The specification, divorced from the context of a use-case, is just bizarre.
A: If I had a need to return two rows: one row with the literal 'assword' and another row "below" it with the literal 'name', I could do this:
( SELECT 'assword' AS some_string )
UNION ALL
( SELECT 'name' AS some_string )
ORDER BY some_string
In this particular case, we can get the ordering we need by a simple reference to the column in the ORDER BY clause.
In the more general case, when there isn't a convenient expression for the ORDER BY clause, I would add an additional column, and perform a SELECT on the resultset from the UNION ALL operation. In this example, that "extra" column is named seq:
SELECT t.some_string
FROM ( SELECT 'assword' AS some_string, 1 AS seq
UNION ALL SELECT 'name', 2
)
ORDER BY t.seq
As another example:
( SELECT 'do' AS tone, 1 AS seq )
UNION ALL ( SELECT 're', 2 )
UNION ALL ( SELECT 'mi', 3 )
UNION ALL ( SELECT 'fa', 4 )
ORDER BY seq
I'd only need to add an outer SELECT if I needed a projection operation (for example, to remove the seq column from the returned resultset.
SELECT t.tone
FROM ( SELECT 'do' AS tone, 1 AS seq
UNION ALL SELECT 're', 2
UNION ALL SELECT 'mi', 3
UNION ALL SELECT 'fa', 4
)
ORDER BY t.seq

Counting comma separated values in TSQL

SCHEMA / DATA for TABLE :
SubscriberId NewsletterIdCsv
------------ ---------------
11 52,52,,52
We have this denormalized data, where I need to count the number of comma separated values, for which I am doing this :
SELECT SUM(len(newsletteridcsv) - len(replace(rtrim(ltrim(newsletteridcsv)), ',','')) +1) as SubscribersSubscribedtoNewsletterCount
FROM TABLE
WHERE subscriberid = 11
Result :
SubscribersSubscribedtoNewsletterCount
--------------------------------------
4
The problem is some of our data has blanks / spaces in between the comma separated values, if I run the above query the expected result should be 3 (as one of the value is blank space), how do I check in my query to exclude the blank spaces?
EDIT :
DATA :
SubscriberId NewsletterIdCsv
------------ ---------------
11 52,52,,52
12 22,23
I need to get an accumulative SUM instead of just each rows sum, so for this above data I need to have just a final count i.e. 5 in this case, excluding the blank space.
Here's one solution, although their may be a more efficient way:
SELECT A.[SubscriberId],
SUM(CASE WHEN Split.a.value('.', 'VARCHAR(100)') = '' THEN 0 ELSE 1 END) cnt
FROM
(
SELECT [SubscriberId],
CAST ('<M>' + REPLACE(NewsletterIdCsv, ',', '</M><M>') + '</M>' AS XML) AS String
FROM YourTable
) AS A
CROSS APPLY String.nodes ('/M') AS Split(a)
GROUP BY A.[SubscriberId]
And the SQL Fiddle.
Basically it converts your NewsletterIdCsv field to XML and then uses CROSS APPLY to split the data. Finally, using CASE to see if it's blank and SUM the non-blank values. Alternatively, you could probably build a UDF to do something similar.

How to: Select from MYSQL text field type only the numbers that start with 89 using REGEXP?

I have tried in many ways to select from text fields only the numbers that start with 89. I don't have a fix length after the first 2 numbers.
How can I do this to work properly and not get numbers like 389xxxxxx in results, for example. THE minimum length should be at least 8 characters.
Thank you!
If your column is integer, then you can probably do something like:
select * from my_table where cast(int_column) as char) like '89______%'
(that's 6 underscore characters before the percentage char)
If it's character value, then you can do this:
SELECT * FROM mytable WHERE char_column REGEXP "^89[[:digit:]]{6,}$"
If your column is numeric with decimal places and you want only integer values, then you need to do something like
SELECT * FROM mytable WHERE cast(numeric_column as char) REGEXP "^89[[:digit:]]{6,}$"
Edit: It seems Tim has edited his answer, which I referred to, so I edited my answer to include his code for column of character type.
SELECT * FROM foo WHERE bar REGEXP "([^0-9]89[0-9]*)|(^89[0-9]*)"
SELECT * FROM mytable WHERE mycolumn REGEXP "(^|[^[:digit:]])89[[:digit:]]{6,}";
will do this:
( # Either match
^ # the start of the string
| # or
[^[:digit:]] # any character except a digit
) # End of alternation.
89 # Match 89
[[:digit:]]{6,} # plus at least 6 more digits.