Snowflake - Operation in VALUES clause - Invalid expression - snowflake-cloud-data-platform

How can we get a rational number in a VALUES clause in Snowflake ?
SELECT * FROM (
VALUES (1/3.0), (2)
) AS t ;
returns :
SQL compilation error: Invalid expression [1 / 3] in VALUES clause

This is so peculiar it could be characterised as a bug.
Any division that results in a whole number works, but fractions trigger the error message.
The Documentation states that:
Each expression must be a constant, or an expression that can be evaluated as a constant during compilation of the SQL statement.
Most simple arithmetic expressions and string functions can be evaluated at compile time, but most other expressions cannot.
Clearly (1/3) should be such a simple arithmetic expression. The simple workaround is of course to calculate the answer and include as a decimal number:
SELECT * FROM (VALUES (0.33333333333333333), (2)) AS T(VAL);
On second thought this is not as straight forward as it seems. If those values are used in a CREATE TABLE AS SELECT statement, should the data type be NUMBER(7,6) or FLOAT or something else? Maybe it is best to be specific in these cases.
The specifics for division etc are documented in Scale and Precision in Arithmetic Operations.

if you know you have a large number of rational input you want you can just do the math in the select
SELECT column1/column2 FROM VALUES (1,3),(2,1);
giving:
COLUMN1/COLUMN2
0.333333
2.000000

Related

How to use the SQL Server integer division operator "\"?

According to https://technet.microsoft.com/en-us/library/dd255271(v=sql.110).aspx:
\ Divides two numbers and returns an integer result.
However, I cannot figure out how to use it. All my attempts end up the same - the error
Incorrect syntax near '\ 5'
when trying to do an integer division by 5.
So how do we use the damn thing?
The link that you posted is specific to SSRS (SQL Server Reporting Services). You can use \operator in Reporting Services expressions, which is not the same as T-SQL.
T-SQL does not support \ operator, only / operator. You can see the list of valid arithmetic operators on MSDN
If you are confused about what is Expression and what is T-SQL, expression is basically statement that you use in report, often to process or format the data. T-SQL on the other hand is the language which is used to execute queries and commands on SQL databases.
Do you mean this?
http://sqlfiddle.com/#!3/1d3dd/1
You can divide like this
select 4/2
This will give you 2
If you are looking for to divide and get if any remainder then is %
See an example here http://sqlfiddle.com/#!3/1d3dd/4

Obtaining decimal values in calculations in database

Recently, I came across an anomaly that while dividing two integers, I am getting only the quotients and reminders are simply ignored.
SELECT 12/8,12%8
The above query gives 1 and 4 respectively, which is similar to Java/C programming. Again applying Java/C programming methods used below calculations to obtain the expected value.
SELECT 12.0/8,12/8.0
The answer is 1.5000 and 1.5000 respectively.
Working on my task I got a situation to obtain percentage value across two counted values (integers) and I stuck up with the results similar to the former query. Then I worked out through the same by multiplying one of the value with 1.0 . This solved my issue.
But later on, going through few scripts, used in my project (developed long back), I noticed in certain cases the decimal values are returned from the query even though two counted values (whole numbers) are divided.
I first noticed this in Netezza. But same holds true in SQL Server as well.
Please advise on what basis the datatypes of returned values are decided.
When dividing both integers, it will perform integer division, which returns an integer. To perform floating point division, you must either cast one or both of the operands to float/decimal/double.
SELECT cast(12 as float)/8
SELECT 12/cast(8 as float)
SELECT cast(12 as float)/cast(8 as float)
SELECT cast(12/8 as float)
Note that the last query is different since the integer division is performed first before casting to float,that is why the decimal value was already lost.

Why my result of the operation is rounded down to 0?

I've function in T-SQL:
sum(ar.tothandlingtime)/(60*60*24)
and in my result set I've all 0, because the result of this part of the day. Always is below 0.
I want to continue to work on the results, so I need an accurate result in a form and in a view. How?
It is doing integer division, and thus truncating the decimal.
To get your desired result, try converting one side to a decimal:
CONVERT(decimal(19, 18), SUM(ar.tothandlingtime))/(60*60*24)
Using this lets SQL know to perform decimal-based division.
If you need to, you can also play with the precision and scale of the decimal (read more here: http://msdn.microsoft.com/en-us/library/ms187746.aspx)
Of course, if you don't care about the precision, you can also achieve this by putting .0 after each hard-coded number:
(60.0*60.0*24.0)
For example,
select 5/(60.0*60.0*24.0) -- Result: 0.000057870370
select 5/(60*60*24) -- Result: 0
In my experience, this is generally the quickest way to get it to register as decimal division without explicitly using a CAST or CONVERT. If you were strictly using integer-based column values or aggregate functions, though, you would need to convert it, like in the first example.
You are dividing by an int trying converting that to a decimal. Change it like this
sum(ar.tothandlingtime)/CAST((60*60*24) AS DECIMAL ))

SQL Server : SUM() weird behaviour

I run this example in SQL Server Management Studio:
SELECT CONVERT(REAL, -2101.12) n INTO #t
SELECT * FROM #t
SELECT SUM(n) FROM #t
The first SELECT creates a temp table #t with 1 column n of type real, and it puts 1 row in it with the value -2101.12.
The second SELECT confirms that the table is created with the intended content and the result is:
n
---------
-2101.12
The third SELECT sums the only number that is there, but the result is:
-2101.1201171875
So the question is: Where the 0.0001171875 comes from?
EDIT: I know the lack of precision for the real and float data types, unfortunately I cannot change the database schema because of this. What surprise me though, is that I would expect to see also the extra decimals in the second select since it is supposed to be stored with that lack of precision. Since it does not happens on the second select, then why the sum function picks it up?
You've just discovered real (aka floating point) data is approximate.
Use decimal datatype instead.
The FLOAT and REAL data types are known as approximate data types. The behavior of FLOAT and REAL follows the IEEE 754 specification on approximate numeric data types.
Approximate numeric data types do not store the exact values specified for many numbers; They store an extremely close approximation of the value. For many applications, the tiny difference between the specified value and the stored approximation is not noticeable. At times, though, the difference becomes noticeable. Because of the approximate nature of the FLOAT and REAL data types, do not use these data types when exact numeric behavior is required, such as in financial applications, in operations involving rounding, or in equality checks. Instead, use the integer, decimal, money, or smallmoney data types.
Avoid using FLOAT or REAL columns in WHERE clause search conditions, especially with the = or <> operators. It is best to limit FLOAT and REAL columns with > or < comparisons.
Source of above statement

SQL Server AVG with Decimals & Floats

Basically, two queries that do a similar averaging, are giving me different results; the "actual" value expected is 81.25, so with normal rounding, you would think that CAST-ing it to DECIMAL(10,1) would result in 81.3, but one of the queries (the first one) gives 81.2
Here's the examples:
CAST( AVG( t1.NumCorrect / 7.0 * 100.0 ) AS decimal(10,1))
vs.
CAST( AVG( t2.PercentCorrect ) AS decimal(10,1))
The only difference, as far as I can tell, is that PercentCorrect is type REAL, and NumCorrect is type FLOAT.. but those are both floating-point types, so why would casting them behave differently?
In the first line, NumCorrect is like a "# correct out of 7 possible", so I'm calculating a "Percent" on-the-fly, which is then AVG'd; whereas in the 2nd example, the Percent is pre-calculated, and I just need it AVG'd. Again, first line is the one that gives 81.2 instead of 81.3
If I need to provide more context with the surrounding queries or source-data, I can try... just let me know.
Execute this on SQL and you'll get your answer.
select 1425554.3/5457.251
select convert(real, (1425554.3/5457.251))
Basically, t2.PercentCorrect is already casted/converted to real which truncates the decimal point values. t1.NumCorrect is divided on the fly and all decimal points are processed on the avg function.
Hope this helps!
The easiest way is to divide by 1.0 and it will produce 6 digit precision.
Example:
select avg(incomeamount/1.0),vendorid from dailyincome group by vendorid

Resources