Integer function in snowsql - snowflake-cloud-data-platform

I am trying to run this query in snowflakes, but I keep having the error below. Can someone please tell me what I am doing wrong. I am trying to get the integer value for the ages.
SELECT DISTINCT Target_quikvalf.MPOLICY
FROM Target_quikvalf
WHERE (((Target_quikvalf.MPOLICY) Like '%N')
AND ("DATE" (Target_quikvalf.MISSUE) Between '5/1/2020' And '5/31/2020')
AND (as_integer((Target_quikvalf.MAGE) / 5)*5))
Error Message:
SQL compilation error: invalid type [FLOAT] for parameter 'AS_INTEGER(variantValue...)'

The placement of where you are applying the function is the issue. Here we are converting the data type before applying the mathematical calculations.
You'll need to cast the FLOAT to INT can cast it like so:
SELECT DISTINCT Target_quikvalf.MPOLICY
FROM Target_quikvalf
WHERE (((Target_quikvalf.MPOLICY) Like '%N')
AND ("DATE" (Target_quikvalf.MISSUE) Between '5/1/2020' AND '5/31/2020')
AND ((cast(Target_quikvalf.MAGE as int) / 5) * 5);
As an alternative, we can try converting the FLOAT to a number using TO_NUMBER. If Target_quikvalf.MAGE column was a variant data type, then you'd be able to run it like so (in the example below, we are forcing the converted float number to not have a tenths place and can support ages below 1000 since people can be over 100 years old):
SELECT DISTINCT Target_quikvalf.MPOLICY
FROM Target_quikvalf
WHERE (((Target_quikvalf.MPOLICY) Like '%N')
AND ("DATE" (Target_quikvalf.MISSUE) Between '5/1/2020' AND '5/31/2020')
AND ((to_number(Target_quikvalf.MAGE, 3, 0) / 5) * 5);

SELECT as_integer(5.1);
generates
SQL compilation error: invalid type [NUMBER(2,1)] for parameter 'AS_INTEGER(variantValue...)'
so don't use a function that is intended to "parsing variant data" to truncate you number, instead
cast
SELECT 5.1::int;
gives:
5.1::INT
5
given you are not getting the value scaled as you expect, let break it down:
SELECT 68 as age
, age/5 as float_scale
, float_scale::int as cast_age
, round(float_scale,0) as round_age
, trunc(float_scale,0) as trunc_age
, trunc_age * 5 as scaled_back;
gives:
AGE FLOAT_SCALE CAST_AGE ROUND_AGE TRUNC_AGE SCALED_BACK
68 13.600000 14 14 13 65
casting, and rounding appear to not be what you want, thus TRUNC is the key here
thus your code should be
(TRUNC(Target_quikvalf.MAGE / 5) *5)

Related

Unable to perform arithmetic operation in select statement in specific scenario

While I was doing some multiplication in select statements, I found a special case where SQL Server is throwing an arithmetic overflow error.
When I executed the same in W3Schools SQL window, it worked. Below is my query where it is throwing error. I tried multiple permutations and combinations but it failed in most of the cases
SELECT 20000000 * 130
Msg 8115, Level 16, State 2, Line 4
Arithmetic overflow error converting expression to data type int.
Message window:
Output window:
Version information:
type int isn't enought, try float.
SELECT cast(20000000 as float) * cast(130 as float)
The result is the data type of the argument with the higher precedence. But if you have 2 int you can't get a float without casting
https://learn.microsoft.com/it-it/sql/t-sql/language-elements/multiply-transact-sql?view=sql-server-2017
I had used float but bigint is the same
SELECT CAST(20000000 AS BIGINT) * 130

Simple SELECT query with calculated columns returns error

I have a query:
use [Some_Database];
go
select toip 10 IDEVENT,
COUNT(*)
from [AL_PROTOCOL]
group by IDEVENT
order by Quanity desc
go
In output I get results as
IDEVENT Quanity
664 4,037787E+07
566 2,124254E+07
438 1,248467E+07
294 9926404
564 9777449
436 5784661
310 5709771
428 5161083
432 5154893
434 5150308
So, then I try to calculate second (*60 / 1,000,000) column using CONVERT (real (100), COUNT(*)*60/1000000, 2) as 'Size, Mb'
next way:
use [Some_Database];
go
select top 10 IDEVENT,
COUNT(*),
CONVERT (real (100), COUNT(*)*60/1000000, 2) as 'Size, Mb'
from [AL_PROTOCOL]
group by IDEVENT
order by Quanity desc
go
After this, I get this error
8115 'Arithmetic overflow error converting expression to int type
numeric'.
Technet explains, that this kind of errors occurs when a value in the column is overgrowing the maximal size of integer type. But, why doesn't it convert in REAL type?
Also, this question solved by replacing '*60/1,000,000' on '/1,000,000*60', but my interest is not satisfied.
What am I doing wrong? thanks
Look carefully at the order of operations you have asked the DBMS to perform. CONVERT (real (100), COUNT(*)*60/1000000, 2) means:
COUNT(*)
result * 60
result / 1000000
CONVERT (real (100), result, 2)
Until step 4, the value is still an integer, so you get an overflow error if COUNT(*) * 60 is higher than the maximum representable integer.
Because * and / have the same precedence, the workaround you found is CONVERT (real (100), COUNT(*)/1000000*60, 2), which means:
COUNT(*)
result / 1000000
result * 60
CONVERT (real (100), result, 2)
We're still doing maths on integers, but now we never overflow because we divide before multiplying.
But what you actually wanted was to do all the maths on the floating point value:
COUNT(*)
CONVERT (real (100), result, 2)
result * 60
result / 1000000
For that, you just need to swap the nesting around so that you convert the COUNT(*) result directly, and then apply the maths: CONVERT (real (100), COUNT(*), 2) * 60 / 1000000
If you multiply a really large number by 60, you're going to get an even bigger number, increasing the chances of an arithmetic overflow. The fact that you divide it by 1,000,000 after is too late, you've already tried to generate a number that is too big to proceed with.
However, when you divide it by 1,000,000 first before multiplying by 60, then you are always going to get a smaller number, so you should never get an arithmetic overflow.
Also, with your CONVERT, you are doing it on the entire result, and all of the numbers in the calculation are of INT types, so it will generate an INT before the conversion.
COUNT(*)*60/1000000 -- COUNT(*) is an INT, as well as the other numbers
If you change the ordering of the CONVERT \ CAST it should work.
DECLARE #number AS INT
SET #number = 123456789
-- this doesn't work
SELECT CAST((#number * 60) AS REAL(100))
-- this does
SELECT CAST(#number AS REAL(100)) * 60

How to multiply a large number in sql with out getting a "overflow error " error

I know this maybe a silly question; but how do I multiply large numbers in SQL Server without getting this error:
Arithmetic overflow error converting expression to data type int
I need to take a column that contains a list of 6 digit client numbers.
E.g. 123456, 123457 and make it 1234560000000, 1234570000000 & etc.
This is what I tried doing.
update account set sClientIdNo = sClientIdNo * 100000000
But I end up with the overflow error.
Any help will be greatly appreciated.
Edit: i forgot to mention that the column which contained the client numbers had a varchar data type.
This is what worked for me.
UPDATE account SET sClientIdNo = CONVERT(bigint, sClientIdNo ) * 100000000
#shA.t Provided the clue i needed by declaring #a a numeric.
Thanks
I can suggest you to use numeric type like this:
DECLARE #a numeric(14, 0) = 123456
SELECT #a * 100000000
Note that I use 14 for your requirement you can use bigger values for precision.

How do I do decimal arithmetic on two varchars and return result to an aliased column?

I have two fields of type varchar that contain numeric values or blank strings, the latter of which I have filtered out to avoid Divide by Zero errors.
I am attempting to determine the percentage value that num2 represents in relation to num1, i.e. (Num_2 * 1 / Num_1). Relatively simple math.
The problem I am having is that I cannot seem to do the math and then cast it to a decimal value. I keep receiving Arithmetic overflow error converting int to data type numeric errors.
Can someone help me out with the casting issue?
You didn't interpret the error correctly.
It is not about casting the result of your math to float, it is about implicit type casting before the equation is evaluated.
You have in your table some values that cannot be converted to numeric, because they are not valid numbers or numbers out of range. It is enough that one row contains invalid data to make fail the whole query.
perhaps you're looking for something similar to this?
declare #table table (
[numerator] [sysname]
, [denominator] [sysname]);
insert into #table
([numerator],[denominator])
values (N'1',N'2'),
(N'9999999999',N'88888888888');
select case
when isnumeric([numerator]) = 1
and isnumeric ([denominator]) = 1
then
cast([numerator] as [float]) / [denominator]
else
null
end
from #table;
Is this what you're looking for?
select cast('25.5' as decimal(15, 8)) / cast('100.0' as decimal(15, 8))
The example above will return this:
0.25500000000000000000000
In this case, I'm converting the operand types before they get used in the division.
Remember to replace the literals in my query by your field names.
you said that can be number or blank string.
son try something like this:
SELECT
(CASE WHEN NUM_2 = '' THEN 0 ELSE CAST(NUM_2 AS NUMERIC(15,4)) END)
/
(CASE WHEN NUM_1 = '' THEN 1 ELSE CAST(NUM_1 AS NUMERIC(15,4)) END)
you test if string is blank. if it is, you use 0 (or 1, to avoid division by zero)

SQL Server CAST from varchar to numeric fails with error

I have a column of data that contains 9 digits of numeric values, but the column is defined as a varchar. I need to CAST the field to a numeric value so I can divide the sum of the column by 100. e.g.
select CAST(field1 as numeric(9,2)) / 100 from table;
I get the following error when running the query: Arithmetic overflow error converting varchar to data type numeric.
If I perform a double CAST from varchar -> int -> numeric, the CAST works. e.g.
select CAST(CAST(field1 as int) as numeric(9,2)) / 100 from table;
Is there a reason why the single CAST from varchar -> numeric results in a SQL error, but the double CAST works?
If your field contains 9 digits, it could be a max of 999,999,999. My original thought was that your cast should be CAST (NUMERIC 11, 2)
edit
To be on the safe side, with 9 character length, you could have numbers ranging from 999,999,999 to 0.1234567. This means you need 9 digits before the decimal point and 7 after (total 16). Therefore your cast should be CAST (NUMERIC (16,7)
select CAST(field1 as numeric(16,7) from table;
The cause of the error was one row that had '-' as the value for the field. CASTing directly to NUMERIC doesn't work, but CASTing to INT first forced the '-' fields to return 0.

Resources