String to double or decimal - exact-online

How to convert a string to a double or decimal? In Exact Online (REST API) I try to calculate with a decimal value in a string field. e.g items.netprice + items.notes. The field items.notes contains the decimal value.
Tried using cast and convert in combination with float and decimal.

I would use a solution like:
select case
when regexp_replace(c, '[^0-9.]', '', 1, 0, 'g') = c
then to_number(c)
else null
end
from ( select '123.45' c
from dual#datadictionary
union all
select '123invalid.45' c
from dual#datadictionary
)
The case with regexp_replace ensures that non-number are returned as null. You might want to change that to an error if deemed necessary.

Related

Split column value and return split values appropriately

I have below table (MYSQL),
CREATE TABLE x_table (name VARCHAR(100), currencyType VARCHAR(100));
INSERT INTO x_table VALUES ('Rupee', '5X34'), ('Dollar', '3X34$'), ('Yen', '7X57');
I want to split currencyType column into two.
split currentyType column by X
return count (count must be an int value - not string)
for Rupee - count is 5,
for Dollar - count is 3
return type
for Rupee - 34 doesn't contain $, so type will be 'Non-dollar'
for dollar - 34$ contains $, type would be "dollar'
for yen - 57 doesn't contain $, type would be "Non-dollar'
Tried
select name,
SUBSTRING_INDEX(currencyType, 'X', 1) as count,
SUBSTRING_INDEX(currencyType, 'X', 2) as type
from x_table
but not sure how to implement it correctly.
DEMO
Modify your query as the following:
SELECT
name,
CAST(SUBSTRING_INDEX(currencyType, 'X', 1) AS UNSIGNED) AS count,
CASE
WHEN INSTR(SUBSTRING_INDEX(currencyType, 'X', -1), '$')
THEN 'dollar' ELSE 'Non-dollar'
END AS type
FROM x_table
See demo
CAST(SUBSTRING_INDEX(currencyType, 'X', 1) AS UNSIGNED): this will cast the left part of the string as positive number.
To start searching the string from right (get the right part of the string), use -1 instead of 1 for the number parameter in the substring_index function
The INSTR function check if the string contains '$' or not.

MYSQL: Validate Input Values in Specific Format within a FUNCTION

i have one question with regard to MYSQL. I want to create a function that is able to check whether an Input is given in a specific format.
The output should be in the following shape:
***x x (a) n (n) (n) (n)
with :
x = letters and numbers
n = numbers
a = letters
brackets = optional Values***
my code is written below this.
CREATE FUNCTION validate_of_number(testnumber VARCHAR(7))
RETURNS INT
DETERMINISTIC
RETURN
CASE
WHEN
(SELECT * FROM flightexecution WHERE FlightNo REGEXP
'^[[:alnum:]+[:alnum:]] + [[:alpha:]|''] + [:digit:] +
[[:digit:]|''] + [[:digit:]|''] + [[:digit:]|'']') > 0
Then 1
Else 0
END;`
However, it does not work and i don´t know why. The Output is just a 'OK' without any further information.
I'm assuming based on your description of valid values and the context of your question that the values you are trying to validate look something like CX727 or QF1566 or BA1 etc (i.e. IATA flight designator codes). In that case, this function will give you the results you want:
CREATE FUNCTION validate_of_number(testnumber VARCHAR(7))
RETURNS INT
DETERMINISTIC
RETURN testnumber REGEXP '^[[:alnum:]]{2}[[:alpha:]]?[[:digit:]]{1,4}$';
Examples:
SELECT validate_of_number('A1B4352')
, validate_of_number('QF12')
, validate_of_number('CX727')
, validate_of_number('AB14352')
, validate_of_number('BA1')
, validate_of_number('1C42')
Output
1, 1, 1, 0, 1, 1
Demo on dbfiddle
In terms of using it with your table you might use a query like
SELECT * FROM flightexecution WHERE validate_of_number(FlightNo)

Teradata Masking - Retain all chararcters at position 1,4,8,12,16 .... in a string and mask remaining characters with 'X'

I have a requirement where I need to mask all but characters in position 1,4,8,12,16.. for a variable length string with 'X'
For example:
Input string - 'John Doe'
Output String - 'JXXn xxE'
SPACE between the two strings must be retained.
Kindly help or reach out for more details if required.
I think maybe an external function would be best here, but if that's too much to bite off, you can get crafty with strtok_split_to_table, xml_agg and regexp_replace to rip the string apart, replace out characters using your criteria, and stitch it back together:
WITH cte AS (SELECT REGEXP_REPLACE('this is a test of this functionality', '(.)', '\1,') AS fullname FROM Sys_Calendar.calendar WHERE calendar_date = CURRENT_DATE)
SELECT
REGEXP_REPLACE(REGEXP_REPLACE((XMLAGG(tokenout ORDER BY tokennum) (VARCHAR(200))), '(.) (.)', '\1\2') , '(.) (.)', '\1\2')
FROM
(
SELECT
tokennum,
outkey,
CASE WHEN tokennum = 1 OR tokennum mod 4 = 0 OR token = ' ' THEN token ELSE 'X' END AS tokenout
FROM TABLE (strtok_split_to_table(cte.fullname, cte.fullname, ',')
RETURNS (outkey VARCHAR(200), tokennum integer, token VARCHAR(200) CHARACTER SET UNICODE)) AS d
) stringshred
GROUP BY outkey
This won't be fast on a large data set, but it might suffice depending on how much data you have to process.
Breaking this down:
WITH cte AS (SELECT REGEXP_REPLACE('this is a test of this functionality', '(.)', '\1,') AS fullname FROM Sys_Calendar.calendar WHERE calendar_date = CURRENT_DATE)
This CTE is just adding a comma between every character of our incoming string using that regexp_replace function. Your name will come out like J,o,h,n, ,D,o,e. You can ignore the sys_calendar part, I just put that in so it would spit out exactly 1 record for testing.
SELECT
tokennum,
outkey,
CASE WHEN tokennum = 1 OR tokennum mod 4 = 0 OR token = ' ' THEN token ELSE 'X' END AS tokenout
FROM TABLE (strtok_split_to_table(cte.fullname, cte.fullname, ',')
RETURNS (outkey VARCHAR(200), tokennum integer, token VARCHAR(200) CHARACTER SET UNICODE)) AS d
This subquery is the important bit. Here we create a record for every character in your incoming name. strtok_split_to_table is doing the work here splitting that incoming name by comma (which we added in the CTE)
The Case statement just runs your criteria swapping out 'X' in the correct positions (record 1, or a multiple of 4, and not a space).
SELECT
REGEXP_REPLACE(REGEXP_REPLACE((XMLAGG(tokenout ORDER BY tokennum) (VARCHAR(200))), '(.) (.)', '\1\2') , '(.) (.)', '\1\2')
Finally we use XMLAGG to combine the many records back into one string in a single record. Because XMLAGG adds a space in between each character we have to hit it a couple of times with regexp_replace to flip those spaces back to nothing.
So... it's ugly, but it does the job.
The code above spits out:
tXXs XX X XeXX oX XhXX fXXXtXXXaXXXy
I couldn't think of a solution, but then #JNevill inspired me with his idea to add a comma to each character :-)
SELECT
RegExp_Replace(
RegExp_Replace(
RegExp_Replace(inputString, '(.)(.)?(.)?(.)?', '(\1(\2[\3(\4', 2)
,'(\([^ ])', 'X')
,'(\(|\[)')
,'this is a test of this functionality' AS inputString
tXXs XX X XeXX oX XhXX fXXXtXXXaXXXy
The 1st RegExp_Replace starts at the 2nd character (keep the 1st character as-is) and processes groups of (up to) 4 characters adding either a ( (characters #1,#2,#4, to be replaced by X unless it's a space) or [ (character #3, no replacement), which results in :
t(h(i[s( (i(s[ (a( (t[e(s(t( [o(f( (t[h(i(s( [f(u(n(c[t(i(o(n[a(l(i(t[y(
Of course this assumes that both characters don't exists in your input data, otherwise you have to choose different ones.
The 2nd RegExp_Replace replaces the ( and the following character with X unless it's a space, which results in:
tXX[s( XX[ X( X[eXX( [oX( X[hXX( [fXXX[tXXX[aXXX[y(
Now there are some (& [ left which are removed by the 3rd RegExp_Replace.
As I still consider me as a beginner in Regular Expressions, there will be better solutions :-)
Edit:
In older Teradata versions not all parameters were optional, then you might have to add values for those:
RegExp_Replace(
RegExp_Replace(
RegExp_Replace(inputString, '(.)(.)?(.)?(.)?', '(\1(\2[\3(\4', 2, 0 'c')
,'(\([^ ])', 'X', 1, 0 'c')
,'(\(|\[)', '', 1, 0 'c')

Convert decimal to euro currency in MYSQL

What is the best way to select a decimal value from the mysql database and convert it to an euro currrency in the mysql selection.
When i select "format(multiplier * (coalesce(Invoice.rent, 0) + coalesce(Invoice.furnished, 0) + coalesce(Invoice.gwe, 0) + coalesce(Invoice.service, 0) + coalesce(Invoice.gas, 0) + coalesce(Invoice.electricity, 0) + coalesce(Invoice.water, 0) + coalesce(Invoice.heat, 0) + coalesce(Invoice.tax, 0) + coalesce(Invoice.internet_tv, 0)) - coalesce(sum(Payment.amount),0),2)"
It returns a number like this 1,000.25 i want it to be 1.000,25 what is the best way to do this in MYSQL select query?
The documentation reveals that FORMAT() has up to three arguments (emphasis mine):
FORMAT(X,D[,locale])
Formats the number X to a format like '#,###,###.##', rounded to D
decimal places, and returns the result as a string. If D is 0, the
result has no decimal point or fractional part.
The optional third parameter enables a locale to be specified to be
used for the result number's decimal point, thousands separator, and
grouping between separators. Permissible locale values are the same as
the legal values for the lc_time_names system variable (see Section
10.7, “MySQL Server Locale Support”). If no locale is specified, the default is 'en_US'.
That could be a starting point. (You apparently want the format provided by the de_DE locale.)
Demo
In database you cant change default decimal separator from . to , for reason described here insert-non-english-decimal-points-in-mysql.
You can use this function to format your output value:
CREATE FUNCTION f_change_decimal_separator(num_value VARCHAR(16)) RETURNS VARCHAR(16)
BEGIN
DECLARE char_value VARCHAR(16);
SET char_value = REPLACE(num_value, ".", ";");
SET char_value = REPLACE(char_value, ",", ".");
SET char_value = REPLACE(char_value, ";", ",");
RETURN char_value;
END;

How to format int to price format in SQL?

I select the price 1000000 and I need to format it to $1,000,000. How can I do that in SQL?
To format with commas, you can use CONVERT with a style of 1:
declare #money money = 1000000
select '$' + convert(varchar, #money, 1)
will produce $1,000,000.00
If you want to remove the last 3 characters:
select '$' + left(convert(varchar, #money, 1), charindex('.', convert(varchar, #money, 1)) - 1)
and if you want to round rather than truncate:
select '$' + left(convert(varchar, #money + $0.50, 1), charindex('.', convert(varchar, #money, 1)) - 1)
Creating Function:
CREATE FUNCTION [dbo].[f_FormatMoneyValue]
(
#MoneyValue money
)
RETURNS VARCHAR(50)
AS
BEGIN
RETURN cast(#MoneyValue as numeric(36,2))
END
Using in Select Query:
Select dbo.f_FormatMoneyValue(isnull(SalesPrice,0))SalesPrice from SalesOrder
Output:
100.00
Formatting Money Value with '$' sign:
CREATE FUNCTION [dbo].[f_FormatMoneyWithDollar]
(
#MoneyValue money
)
RETURNS VARCHAR(50)
AS
BEGIN
RETURN '$' + convert(varchar, #MoneyValue, 1)
END
Output:
$100.00
Note: The above sample is for the money field. You can modify this function according to your needs
Hope this helps you..! :D
SELECT FORMAT(price, 'C2', 'en-us')
The SQL Server money datatype is just decimal(10, 4). To my knowledge there is no datatype that will present the way you want.
Adding the dollar sign and commas is something that should belong in the application logic, but if you really must do it through a database object consider adding the dollar sign, and commas every three characters (after the decimal point). In other words, you'll have to convert the int to varchar and do string manipulation.
It depends, however, there's no simple way to do it in standard SQL specs(SQL-92, SQL-2003, etc.).
For PostgreSQL PL/pgSQL and Oracle PL/SQL, you can use to_char to format numbers:
select to_char(1234567.123, 'FM$999,999,999.99')
Which gives output:
$1,234,567.12
See: http://www.postgresql.org/docs/7/static/functions2976.htm