Format from decimal to money SQL Server 2019 - sql

I need this type of decimal number format because what I show refers to money. SP SQL Server 2019
I need to transform from this $25,000.00 a $25.000,00.
Someone could help me?
REPLACE(REPLACE(CONVERT(varchar,CAST(#MontoFinal AS money),1),'.',','),',','.') = 117.692.05

Formatting is usually best handled by the UI, but sometimes you have to do it in the database for various reasons. Sometimes you have to live with mandates, and if you have to do it in the database, it can be done.
Looking at your desired output, you want periods as separators and a comma as a decimal point, and you would also like a dollar sign. Luckily for you, this is how Argentina formats its currency, so you can just use the built-in FORMAT function. The culture string for Argentina is es-AR, so you can use that along with FORMAT:
SELECT FORMAT(123456789, 'C', 'es-AR') AS [Example];
This yields:
Example
$ 123.456.789,00
If your data is a number, you are done. If it is stored as text like in your example, you can CAST it as you were doing:
SELECT FORMAT(CAST('$25,000.00' AS MONEY), 'C', 'es-AR') AS [Example];
Which gives your desired output:
Example
$ 25.000,00
As a final note, the FORMAT function in this scenario puts a space between the dollar sign and the leading number - if you don't want the space, you can remove it:
SELECT REPLACE(FORMAT(CAST('$25,000.00' AS MONEY), 'C', 'es-AR'), ' ', '') AS [Example];
And that gives you:
Example
$25.000,00
There are other ways to get a similar result, but this is probably the easiest (I said easiest, I did not say anything about performance).
If your data is actually text and already has the correct commas and decimal points along with the dollar sign, you could use REPLACE - first replace . with something (I used _), then REPLACE the , with ., and finally REPLACE the _ with . :
SELECT REPLACE(REPLACE(REPLACE('$25,000.00', '.', '_'), ',', '.'), '_', ',') AS [Example];
And again it gives your desired output:
Example
$25.000,00
If your data is not in a consistent format to start with correct commas and decimal points, the FORMAT approach will probably work better for you.

Related

Formatting a string to 2 decimal places?

I have a number that looks like this:
'0000040000'
How can I turn it into a string that looks like this:
400.00
This should work on numbers like this as well :
1234540067 -> 12345400.67
I suspect it's fair to say you have a string that you would like to format as a number.
If you want to "learn" how to do this, I suggest looking up the convert, cast and format functions for SQL Server and gain some extra knowledge.
I've elected to first convert to a numeric type, divide by 100 and format the output.
This saves the need to trim leading zero's.
select format(convert(numeric(18,2), '0000040001') / 100, '0.00'))
Following SQL expression will first change string to decimal and then convert it back to a string in a required format:
SELECT FORMAT(CAST ('0000040000' AS DECIMAL(12,2))/100,'#.00')
This should work:
select convert(varchar(10), convert(decimal(10, 2), try_convert(int, '0000040000') / 100.0))
Why do you want the value as a string? Does a decimal work for your purposes?
Another method is:
select ltrim(str(try_convert(int, '0000040000') / 100.0, 10, 2))
Or using just string manipulations:
select replace(ltrim(replace(stuff('0000040000', 9, 0, '.'), '0', ' ')), ' ', '0')
This would be more elegant if ltrim() in SQL Server accepted the character to trim (as most other databases allow).
Here are a some possible solutions:
DECLARE #x CHAR(10)='0000040000'
SELECT CONVERT(VARCHAR(11),CONVERT(NUMERIC(10,2),CONVERT(NUMERIC(10),#x)/100))
SELECT CONVERT(VARCHAR(11),CONVERT(NUMERIC(10,2),STUFF(#x,9,0,'.')))
Simple as this:
SELECT ROUND('0000040004', 2, 1)/100;
Tested this with SQL Server 2017. It does not care about the fact that the number is a string, it does math on it just fine. Result of the above is 400.04
Your query is more of mathematical one.
To get the last 2 numbers after decimals, get the remainder of the number by dividing it by 100.
To get the digits, leaving the last 2 digits, divide the number by 100 again.
select convert(varchar,1234540067/100)+'.'+ convert(varchar,1234540067% 100);

Search for multiple phone number formats in database

I got a database with a user table. This table contains a column phonenumber. The problem is that its fields use multiple number patterns.
The current patterns I found:
06403/975-0
+496403975 0
06403 975-0
06403 975 0
+49 6403 975 0
When searching for a user in the database, is there a way to search for all number patterns?
SELECT id FROM user WHERE phone = '0123456789'
I use Oracle and MS SQL
Assuming your question means this:
"Is it possible to remove all the non-digit characters from the stored phone number, before making the comparison in the WHERE clause?"
a possible solution looks like this:
...
where translate(phone, '0123456789' || phone, '0123456789') = <input value here>
TRANSLATE will translate every digit to itself, and all other characters in phone to nothing (they will simply be deleted from the string). This is exactly what you want.
If you find that the query is slow, you may want to create a (function-based) index on translate(phone, '0123456789' || phone, '0123456789').
EDIT: I missed the part where you said you are using both Oracle and SQL Server. I did a quick search and found that SQL Server does not have a function similar to Oracle's TRANSLATE. I will leave it to SQL Server experts to help you with that part; I don't know SQL Server.
In Oracle you could do it like this. Strip out the non-numeric characters with translate() to get the phone number. You need to handle the leading zero or international dialling code:
select username from your_table
where translate(phone, '1234567890+/ -', '1234567890') in ('064039750', '4964039750')
You may need to tweak this if you don't know what the international dialling code is.
Obviously the actual problem is one of data quality: the application should enforce a strict format on phone numbers. One bout of data cleansing on write saves a whole bunch of grief on read.
You have a database containing phone numbers. These are sometimes in international format, but often in some national format, probably German, where two leading zeros introduce a country code, while a single leading zero would introduce an area code instead (assuming the home country Germany then). Moreover, a phone number can contain symbols for readability, namely '-', '/', and ' '.
So
+49 12/3456-7 means +491234567 of course
00441234567 means +441234567
04412345 means +494412345
I suggest you convert all numbers into international format in these steps:
replace a leading + with a leading 00, thus making only digits important
remove every character that is not a digit
replace a leading 00 with a leading +
replace a leading 0 with a leading +49
Use Oracle's REGEXP_REPLACE for this:
select
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(trim(phone),
'^\+', '00'), -- leading '+' -> leading '00'
'[^[:digit:]]', ''), -- remove all non-digits
'^00' , '+'), -- leading '00' -> leading '+'
'^0', '+49') -- leading '0' -> leading '+49'
as international_phone
from mytable;
You can do this in the WHERE clause of course:
SELECT id FROM user WHERE regexp_replace(...) = '+49123456789'
or even
SELECT id FROM user WHERE regexp_replace(...phone...) = regexp_replace(...'0123456789'...)
And you may write a PL/SQL function for this for convenience and use it so:
SELECT id FROM user WHERE international_phone(phone) = international_phone('0123456789')
This is for Oracle. There may be something alike for SQL Server.

Adding trailing and leading zeroes

How do we convert and add trailing and leading zeros to a number? For example 123.45. I need to make this ten digits long and have padding numbers in front and back. I would like to convert it to 0001234500. Two trailing numbers after the last digit of the decimal. Remove the decimal. Fill in the remaining space with zeroes for the leading end.
I have this so far and it adds trailing zeroes and removes the decimal.
REPLACE(RIGHT('0'+CAST(rtrim(convert(char(10),convert(decimal(10,4),Field))) AS VARCHAR(10)),10),'.','') as New_Field
In MySQL you would have RPAD and LPAD to get stuff like this done, in SQL Server (2012+) you can get something similar by working with FORMAT.
Easiest way is to FORMAT your numbers with a dot so that they take the right place in the format string, then remove that dot. You need to specify a locale, since in different regions you will get a different decimal sign (even if you use . within the format pattern, you would get , in various locales) - using en-US makes sure you get a dot.
REPLACE(FORMAT(somenumber, '000000.0000', 'en-US'), '.', '')
A few examples:
WITH TempTable(somenumber) AS (
SELECT 3
UNION SELECT 3.4
UNION SELECT 3.45
UNION SELECT 23.45
UNION SELECT 123.45
)
SELECT
somenumber,
REPLACE(FORMAT(somenumber, '000000.0000', 'en-US'), '.', '')
FROM
TempTable;
Gives
3.00 0000030000
3.40 0000034000
3.45 0000034500
23.45 0000234500
123.45 0001234500
You seem to really be overthinking what you need to do here. If we take it in steps, perhaps you'll see that this can be achieved much more easily. This solution runs under the idea that the value 123.45 becomes 0001234500 and 6.5 becomes 0000065000.
Firstly, let's pad out the right hand side of the number 123.45 so that we have 1234500 That's easy enough : 123. 45 * 100 = 12345 So, to get 1234500 we simply need to multiple it by a couple of extra factors of 10:
SELECT 123.45 * 10000; --1234500.00
Ok, now, let's get rid of those decimal places. Easiest way, convert it to an int:
SELECT CONVERT(int, 123.45 * 10000); --1234500
Nice! Now, the finalstep, the leading 0's. A numerical value, in SQL Server, won't display leading zeros. SELECT 01, 001.00; Will return 1 and 1.00 respectively. A varchar however, will though (as it's not a number). We can, therefore, make use of that with a further conversion, and then then use of RIGHT:
SELECT RIGHT('0000000000' + CONVERT(varchar(10),CONVERT(int,123.45 * 10000)),10);
Now you have the value you want '0001234500'.
If you're only after padding, (so 6.5 becomes 0006500) then you should be able to work out how to achieve this with the help above (hint you don't need RIGHT).
Any questions, please do ask.

SQL / REGEX pattern matching

I want to use regex through sql to query some data to return values. The only valid values below returned would be "GB" and "LDN", or could also be "GB-LDN"
G-GB-LDN-TT-TEST
G-GB-LDNN-TT-TEST
G-GBS-LDN-TT-TEST
As it writes the first GB set needs to have 2 characters specifically, and the LDN needs to have 3 characters specifically. Both sets/groups seperated by an - symbol. I kind of need to extract the data but at the same time ensure it is within that pattern. I took a look at regex but I can't see how to, well it's like substring but I can't see it.
IF i undertsand correctly, you could still use of substring() function to extract the string parts separated by -.
select left(parsename(a.string, 3), 2) +'-'+ left(parsename(a.string, 2) ,3) from
(
select replace(substring(data, 1, len(data)-charindex('-', reverse(data))), '-', '.') [string] from <table>
) a
As in above you could also define the length of extracted string.
Result :
GB-LDN
GB-LDN
GB-LDN

Display positive result with a plus sign (+) in SQL

I have the following query:
SELECT
CONVERT(DECIMAL(11,1),SUM(Column/1000*-1)) AS NAME,
FROM
Table
The reason i have "/1000*-1" is that I would like the results to be displayed in units of thousands and inverted (negative values as positive and vice versa) with only one decimal place.
How can I get the positive values have a plus sign (+) in front of them just like the negative values have a dash sign (-) ?
You can use semicolon-separated multi-part strings with the FORMAT function (kind of like you would with custom number formats in Microsoft Excel).
A number format can have up to three sections of formatting code, separated by semicolons. These code sections define the format for positive numbers, negative numbers, and zero values, in that order:
<POSITIVE>;<NEGATIVE>;<ZERO>
example:
FORMAT(#YourValue,'+0.0;-0.0')
(Adapted from this)
I usually also hide zeros when displaying +/- signs so I use formatting string: '+0;-0;'''
SELECT FORMAT(+5,'+0;-0;''') --returns: +5
SELECT FORMAT(-5,'+0;-0;''') --returns: -5
SELECT FORMAT(-5,'+0;-0;''') --returns: <empty string>
To display zero's as well you could use formatting string: '+0;-0;0'
Applies to: tsql, azure-sql-database, sql-server-2012, sql-server-2014, sql-server-2016
More Information:
Microsoft Docs : FORMAT (Transact-SQL)
Microsoft Docs : Formatting Types
(Doc is for .net but also applies to the FORMAT function)
Microsoft Docs : SIGN (Transact-SQL)
SELECT
case
when CONVERT(DECIMAL(11,1),SUM(Column/1000*-1)) >= 0
then concat('+', CONVERT(DECIMAL(11,1),SUM(Column/1000*-1)))
else CONVERT(DECIMAL(11,1),SUM(Column/1000*-1))
end AS NAME
FROM Table
In MYSQL, this works ...
CONCAT(IF(TimeZone>0,'+',''),TimeZone)
SELECT
REPLACE(CONCAT('+', CONVERT(DECIMAL(11,1),SUM(Column/1000*-1))), '+-', '-')
FROM
Table
This approach will show +0.0, though.