CAST numeric to varchar is giving scientific notation - casting

I have three fields that I am trying to concatenate into one large field. Two of the fields are varchar, but one is a float. In certain situations, the concatenated field is showing scientific notation. The concatenated field should be a varchar and show the combination of the three fields regardless of how they are formatted. I am even seeing scientific notation when I just concatenate the two varchar fields when the values have all numbers in them. Why is this occurring and how can I fix it? Here are some examples of ways I am trying to do the concatenation:
Field1 = e.DocumentNo + e.Assignment + CAST(CAST([Amount in LC] as int) as nvarchar(50))
Field2 = CAST(e.DocumentNo + e.Assignment as varchar(255))
I have also tried using CONVERT and it does not provide the expected result. DocumentNo is a varchar(255) and Assignment is a varchar(255), yet when I have these values for each, 5115146916 and 1610000 respectively, Field2 looks like 5.11515E+16.
I also tried to use CONCAT() with the fields and it produces the same undesired result.

Here you go:
IF OBJECT_ID('TEMPDB..#ConcatData','U') IS NOT NULL
DROP TABLE #ConcatData;
CREATE TABLE #ConcatData(
[Amount in LC] [float] NULL,
[Assignment] [varchar](255) NULL,
[DocumentNo] [varchar](255) NULL)
INSERT INTO #ConcatData
VALUES
(-27.08, '20120295', '4820110172'),
(10625451.5124, '20140701', '4810122475'),
(205.5, 'TPE035948900001', '8200022827'),
(10000000, 'TPE035948900001', '8200022827')
SELECT DOCUMENTNO +
ASSIGNMENT +
CASE WHEN RIGHT(str([amount in lc],50,4),4) = '0000'
THEN ltrim(LEFT(str([amount in lc],50,4),LEN(str([amount in lc],50,4))-5))
WHEN RIGHT(str([amount in lc],50,4),3) = '000'
THEN ltrim(LEFT(str([amount in lc],50,4),LEN(str([amount in lc],50,4))-3))
WHEN RIGHT(str([amount in lc],50,4),2) = '00'
THEN ltrim(LEFT(str([amount in lc],50,4),LEN(str([amount in lc],50,4))-2))
WHEN RIGHT(str([amount in lc],50,4),1) = '0'
THEN ltrim(LEFT(str([amount in lc],50,4),LEN(str([amount in lc],50,4))-1))
ELSE ltrim(str([amount in lc],50,4))
END
FROM #ConcatData
Moral of the story here, float isn't the right datatype for your column. I actually don't know when float is the right datatype...
Anyway, the obnoxious CASE statement is needed to remove excess decimal-place zeroes caused by STR(). You might even need more, but this covers you up to 4 decimal places and I think you'll get the idea.
One note, the first THEN removes 5 chars instead of 4. This is to include the . as well.
Output:
482011017220120295-27.08
48101224752014070110625451.5124
8200022827TPE035948900001205.5
8200022827TPE03594890000110000000

Related

Nvarchar '45,56' casted to decimal is 4,00. Nvarchar '45' to tinyint is 4. Why?

There are 2 text boxes called #IMPORTOORARIO and #ANTICIPO.
The user writes in the first one '45,56', and in the second one '45'.
I want to cast the first string to decimal and the second one to tinyint.
No matter what I try: if the cast succeds, I end up with '45,56' casted to 4,00 and '45' to 4.
Just 4. Not 4,00.
Here is part of the store procedure I am using:
INSERT INTO TableName
VALUES
(
try_convert(decimal(6, 2),#IMPORTOORARIO),
try_convert(tinyint,#ANTICIPO)
)
I attach a screenshot to show the problem.
You will see more text boxes and table fields but the problem is always the same, just focus on #IMPORTOORARIO and #ANTICIPO.
#IMPORTOORARIO = number 3. #ANTICIPO = number 4
Info: the maximum number I am going to store in the database is decimal(9, 2).
So something like: 123456,78
So 6 numbers before the comma and 2 after the comma.
To solve the problem, I tried to use CAST, CONVERT, TRY_CONVERT, and something I did not understand with REPLACE:
Select try_convert(numeric(6, 2),replace('25,12', ',', '.'))

How to convert text field with formatted currency to numeric field type in Postgres?

I have a table that has a text field which has formatted strings that represent money.
For example, it will have values like this, but also have "bad" invalid data as well
$5.55
$100050.44
over 10,000
$550
my money
570.00
I want to convert this to a numeric field but maintain the actual numbers that can be retained, and for any that can't , convert to null.
I was using this function originally which did convert clean numbers (numbers that didn't have any formatting). The issue was that it would not convert $5.55 as an example and set this to null.
CREATE OR REPLACE FUNCTION public.cast_text_to_numeric(
v_input text)
RETURNS numeric
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
declare v_output numeric default null;
begin
begin
v_output := v_input::numeric;
exception when others then return null;
end;
return v_output;
end;
$BODY$;
I then created a simple update statement which removes the all non digit characters, but keeps the period.
update public.numbertesting set field_1=regexp_replace(field_1,'[^\w.]','','g')
and if I run this statement, it correctly converts the text data to numeric and maintains the number:
alter table public.numbertesting
alter column field_1 type numeric
using field_1::numeric
But I need to use the function in order to properly discard any bad data and set those values to null.
Even after I run the clean up to set the text value to say 5.55
my "cast_text_to_numeric" function STILL sets this to null ? I don't understand why this sets it to null, but the above statement correctly converts it to a proper number.
How can I fix my cast_text_to_numeric function to properly convert values such as 5.55 , etc?
I'm ok with disgarding (setting to NULL) any values that don't end up with numbers and a period. The regular expression will strip out all other characters... and if there happens to be two numbers in the text field, with the script, they would be combined into one (spaces are removed) and I'm good with that.
In the example of data above, after conversion, the end result in numeric field would be:
5.55
100050.44
null
550
null
570.00
FYI, I am on Postgres 11 right now

DAX to Test for Whole Number

I have a Actuals column like so:
ID | Airport
------------
A | 98.4
B | 98.0
C | 95.3
I'm attempting to format the numbers above into percentages for a front-end report. I have this written in a switch statement - for ease I'll just write the logic as an IF boolean.
example_measure =
VAR Nums = SELECTEDVALUES(Table[Actuals])
VAR FormatNums = IF(DIVIDE(ROUND(nums,1), nums) = 1,
format(nums,"0%"),format(nums,"0.0%")
-
RETURN
FormatNums
no matter what I do this always returns a number with a floating point value of 1f
so in my raw data of 98.0 I'm expecting the format to return "98%" rather than "98.0%"
the measures are used on individual cards, and are filtered so they can only ever show one value or blank, meaning they will only ever display one value on their own.
I've toyed with using if(nums = int(nums) which should evaluate to true for 98.0 but it I always get false.
There is a simpler way - just use built-in formatting codes:
Formatted Actuals =
VAR x = SELECTEDVALUE(Data[Actuals])
RETURN
FORMAT(x, "General Number") & "%"
Result:
Built-in style "General Number" handles your situation correctly, you just need to add % symbol to the formatted string. No need to test for whole numbers.
To convert a column/measure into percentage, you can simply divide the column by 100 and then format it as a percentage. Use the following steps:
Create a new column/measure: Perc_value = Table[Actuals]/100
Then go into the modelling tab, select the created column/measure and format it as a % and limit the number of decimal places to 0
This should give the view you are looking for. Hope this helps.
Edit:
You can use the below formula to achieve the desired result:
Column4 = IF('Table'[Column2]-ROUND('Table'[Column2],0)=0,FORMAT('Table'[Column2]/100,"0%"),FORMAT('Table'[Column2]/100,"0.0%"))
Replace Column2 withyour field and you should be good to go.

Compare duplicates for 4 fields in open SQL

I want to compare if there are duplicates across 4 fields in open SQL.
Scenario: User has 4 fields to input. First name (N1), last name (N2), additional first name (N3) and additional last name (N4).
Right now the algorithm works this way: It concatenates N1 + N2 + % and then also
N2+ N1 + %. So if the user inputs in any of the fields, the query looks for N1N2% or N2N1%. This mean for 2 fields, there are 2! combinations possible. Now with 2 additional fields, this algorithm explodes as there will be 4! combinations to check. Any ideas how to tackle this?
Note: We do this kind of combination check because the user could input data in any of those given input field. So we check for all combination of fields. Unfortunately, this cannot be changed.
EDIT:
I cannot assume the order as it was previously designed in such a way. Hence, the complications with combinations.
Edit2:
I like the idea of checking individual parts. But what we want to do is ideally concatenate all strings together and check for a substring in DB. In open-sql its done using the like statement. Our DB table has such concatenated string already stored for N1+N2 combination. This needs to be extended for 4 fields now.
The key to your problem is checking all name parts individually with leading and trailing '%' and check the total size of the db entry against the sum of the name parts:
field = ('%' + N1 + '%') AND field = ('%' + N2 + '%') AND field = ('%' + N3 + '%') AND field = ('%' + N4 + '%') AND LENGTH(field) = LENGTH(N1+N2+N3+N4)
This will find a match. You could use it to SELECT a normalized concatenation of the names and use GROUP BY and HAVING count(*)>1 to search for duplicates.
If the user does not care about the order and you want to check for duplicates then the following condition seems to meet your criteria I think.
SELECT ...
FROM ...
INTO TABLE ...
WHERE N1 IN (#INPUT_N1, #INPUT_N2, #INPUT_N3, #INPUT_N4)
AND N2 IN (#INPUT_N1, #INPUT_N2, #INPUT_N3, #INPUT_N4)
AND N3 IN (#INPUT_N1, #INPUT_N2, #INPUT_N3, #INPUT_N4)
AND N4 IN (#INPUT_N1, #INPUT_N2, #INPUT_N3, #INPUT_N4).
IF sy-dbcnt > 0.
"duplicates found, do something...
ENDIF.
Of course when there is garbage in the database where for example all the four fields are the same, then this will not return a real duplicate.

Format mask for number field items: trailing and 'leading' zero

I'm having some trouble with displaying numbers in apex, but only when i fill them in through code. When numbers are fetched through an automated row fetch, they're fine!
Leading Zero
For example, i have a report where a user can click a link, which runs a javascript function. There i get detailed values for that record through an application process. The returned values are in JSON. Several fields are number fields.
My response looks as follows (fe):
{"AVAILABLE_STOCK": "15818", "WEIGHT": ".001", "VOLUME": ".00009", "BASIC_PRICE": ".06", "COST_PRICE": ".01"}
Already the numbers here 'not correct': values less than one do not have a zero before the .
I kind of hoped that the format mask on the items would catch this. If i specify FM999G990D000 for the item weight, i'd expect it to show '0.001' .
But okay, i suppose it only works that way when it comes through session state, and not when you set an item value through $("#").val() ?
Where do i go wrong? Is my only option to change my select in the app process?
Now:
SELECT '"AVAILABLE_STOCK": "' || AVAILABLE_STOCK ||'", '||
'"WEIGHT": "' || WEIGHT ||'", '||
'"VOLUME": "' || VOLUME ||'", '||
'"BASIC_PRICE": "' || BASIC_PRICE ||'", '||
Do i need to provide my numberfields a to_char with the format mask here (to_char(available_stock, 'FM999G990D000')) ?
Right now i need to put my numbers between quotes ofcourse, or i get invalid json when i parse it.
Trailing Zero
I have an application process on a page on the after header point, right after an automated row fetch. Several fields are calculated here (totals). The variables used are all specified as number(10, 2). All values are correct and rounded to 2 values after the comma. My format masks on the items are also specified as FM999G999G990D00.
However, when one of the calculated values has only one meaningfull value after the comma, the trailing zeros get dropped. Instead of '987.50', it is displayed as '987.5'.
So, i have a number variable, and assign it like this: :P12_NDB_TOTAL_INCL := v_totI;
Would i need to convert my numbers here too, with format mask?
What am i doing wrong, or what am i missing?
If you aren't doing math on it and are more concerned with formatting, I suggest treating it as a varchar/string instead of as a number wherever you can.