Round up value to nearest whole number in SQL UPDATE - sql

I'm running SQL that needs rounding up the value to the nearest whole number.
What I need is 45.01 rounds up to 46. Also 45.49 rounds to 46. And 45.99 rounds up to 46, too. I want everything up one whole digit.
How do I achieve this in an UPDATE statement like the following?
Update product SET price=Round

You could use the ceiling function; this portion of SQL code :
select ceiling(45.01), ceiling(45.49), ceiling(45.99);
will get you "46" each time.
For your update, so, I'd say :
Update product SET price = ceiling(45.01)
BTW : On MySQL, ceil is an alias to ceiling ; not sure about other DB systems, so you might have to use one or the other, depending on the DB you are using...
Quoting the documentation :
CEILING(X)
Returns the smallest integer value not
less than X.
And the given example :
mysql> SELECT CEILING(1.23);
-> 2
mysql> SELECT CEILING(-1.23);
-> -1

Try ceiling...
SELECT Ceiling(45.01), Ceiling(45.49), Ceiling(45.99)
http://en.wikipedia.org/wiki/Floor_and_ceiling_functions

For MS SQL CEILING(your number) will round it up.
FLOOR(your number) will round it down

Combine round and ceiling to get a proper round up.
select ceiling(round(984.375000), 0)) => 984
while
select round(984.375000, 0) => 984.000000
and
select ceil (984.375000) => 985

Ceiling is the command you want to use.
Unlike Round, Ceiling only takes one parameter (the value you wish to round up), therefore if you want to round to a decimal place, you will need to multiply the number by that many decimal places first and divide afterwards.
Example.
I want to round up 1.2345 to 2 decimal places.
CEILING(1.2345*100)/100 AS Cost

If you want to round off then use the round function. Use ceiling function when you want to get the smallest integer just greater than your argument.
For ex: select round(843.4923423423,0) from dual gives you 843 and
select round(843.6923423423,0) from
dual gives you 844

This depends on the database server, but it is often called something like CEIL or CEILING. For example, in MySQL...
mysql> select ceil(10.5);
+------------+
| ceil(10.5) |
+------------+
| 11 |
+------------+
You can then do UPDATE PRODUCT SET price=CEIL(some_other_field);

Related

Postgres float column sum delta. Update schema or use cast?

It's not a new thing to discuss, but I just want you opinion.
What is a better solution in this case:
there is a column with float values:
Column | Type | Collation | Nullable |
----------------------------------------
work_res | real | | not null |
When I calculate sum over the whole table it gives one value, let's assume 100.2123
select sum(work_res) from work_data
>> 100.2123
But when I work on the same data and group first and after do sum, then sum is 100.9124
select sum(gd.work_res)
from (
select type, sum(work_res) as work_res
from work_data
group by type
) as gd
>> 100.9124
type column is just for example as a column to group by
So the problem is round here. If I will use cast to double precision in the sum function, then numbers are identical.
select sum(cast(work_res as double precision)) from work_data
>> 100.9124
Can you please advise what is better solution for me:
Use casting each time
Update the schema
Values in the column can be in range (0, 1].
For example, it can be: 0.(3), 1, 0.5, 0.(1) and so on
I think in both cases I will still see a small delta. Right?
Thanks a lot

Oracle Number Issue

Good Day,
I have an issue I could use your help with.
A customer would like invoice amounts displayed as follows:
Example Invoice Amounts
-405.12 to be shown as 000000040512
&
-400.00 to be shown as 000000040000
The following query works fine for the 405.12 amount, but for the 400.00 amount it drops the two zeros on the right side
LPAD(REPLACE((invoiceamt*-1),'.',''),12,0)
How may I solve this issue?
Thank You
Aaron
I suggest
to_Char(abs(invoiceamt) * 100, '000000000000')
where
abs - absolute value - get rid of sign (-)
* 100 - removing decimal point
to_Char - final formatting (12 mandatory digits)
Forget the REPLACE, just multiply invoiceamt by -100 and then LPAD to the required length.
Another question has reminded me of the existence of the V format model element:
Returns a value multiplied by 10^n (and if necessary, round it up), where n is the number of 9's after the V.
But you can use zeros instead of 9s to keep leading zeros, and add FM to remove the leading space (which is there for a - symbol for negative values - which you won't have). So you can also do:
with t (n) as (
select -405.12 from dual
union all select -400 from dual
)
select n, to_char(abs(n), 'FM0000000000V00') as result
from t;
N RESULT
---------- -------------
-405.12 000000040512
-400 000000040000

Rounding up with two decimal places usind SQL

I want to a number like 3.5212, becomes 3.53. But using:
select Ceiling(3.5212)
it returns 4.
Can I make it always round up with two decimal places?
One way could be to multiply the value by 100 before ceiling function and then divide the final value by 100 as below.
select Ceiling(3.5212 * 100) / 100
Result:
VAL
--------
3.530000
DEMO

Storing extremely small values in Amazon Redshift

I am creating a table in Amazon Redshift using the following command:
CREATE TABLE asmt.incorrect_question_pairs_unique
AS
SELECT question1,
question2,
occurrences,
occurrences / (SUM(occurrences)::FLOAT) OVER () AS prob_q1_q2
FROM (SELECT question1,
question2,
SUM(occurrences) AS occurrences
FROM asmt.incorrect_question_pairs
GROUP BY question1,
question2
HAVING SUM(occurrences) >= 50)
I also tried an alternate:
CREATE TABLE asmt.incorrect_question_pairs_unique
AS
SELECT question1,
question2,
occurrences,
occurrences::float / SUM(occurrences) OVER () AS prob_q1_q2
FROM (SELECT question1,
question2,
SUM(occurrences) AS occurrences
FROM asmt.incorrect_question_pairs
GROUP BY question1,
question2
HAVING SUM(occurrences) >= 50)
I'd like the column prob_q1_q2 to be a float column, which is why I am converting the denominator/numerator to float. But in the resulting table, I get all zeros in that column.
I would like to point out that the SUM(occurrences) would amount to about 10 Billion, so the column prob_q1_q2 will contain extremely small values. Is there a way to store such small values in Amazon Redshift?
How do I make sure that all the values in the column are non-zero float?
Any help would be appreciated.
METHOD 1 - I have had the same problem! In my case it was million of rows so I Multiplied the result by 10000. whenever I wanted to select values from that column I would divide by 10000 in the select statement to make it even. I know its not the perfect solution but works for me.
METHOD 2 - I created a sample table with Numeric(12,6) datatype and when I imported the result set similar to yours, I can see the float values upto 6 decimal precision.
I guess, the conversion does not work when you use create table AS command, you need to create the table specifying the datatype which enforces the result set to be stored to a certain precision level. Its odd! how the same select returns 0.00 but when inserted into table with enforced column, it returns 0.00333.
If I’ve made a bad assumption please comment and I’ll refocus my answer.
Patthebug,
You might be getting a way too low number which cannot be stored in the FLOAT type of Amazon Redshift. Try using DECIMAL instead, there is no way it cannot store your value it's a 128 bit variable.
The way it works is the following, if the value if too big or in your case too small and it exceeds the max/min value of your type the last digits are trimmed and then the new (trimmed) value is stored in the variable/column of your type.
When it is trimming a big value you lose almost nothing lets say you are trimming 20 cents out of 20 billion dollars, you wont be hurt much. But in your case when the number is too small you can loose everything when it trims the last digits to fit in the type
(f.e. A type can store up to 5 digits and you want to store a value of 0.000009 in a variable/column of this type. Your value cannot be fit in the type so its trimmed from the last 2 digits so it can be fit and you receive a new value of 0.0000 )
So if you followed my thought just changing the ::float to ::decimal should fix your issue.
P.S. decimal might require specifying it's size f.e. decimal(127,100)
Try:
select cast(num1 as float) / cast(num2 as float);
This will give you results upto 2 decimal places (by default), but takes up some of your processing time. Doing anything else will round-off the decimal part.
You can have up to 38 digits in a DECIMAL/NUMERIC column with of 37 digits of scale.
CREATE TEMP TABLE precision_test (test NUMERIC(38,37)) DISTSTYLE ALL
;
INSERT INTO precision_test
SELECT CAST( 0.0000000000000000000000000000000000001 AS NUMERIC(38,37)) test
;
SELECT * FROM precision_test
;
--Returns 0.0000000000000000000000000000000000001

Greater than in ActiveRecord query fails with floats?

I need to calculate ranking for values in my Rails app.
I was following example in this question
def rank
User.where("points > ?", points).count + 1
end
Initially I verfied it with integers and it was working. But I also have need to rank floats.
For example, I have following values
0.6238564767774734
0.03700210614260772
0.022441047654982744
0.00935025180031852
0.0016195952859973067
0.0010382902478650936
0.0009367068270665785
0.0004916500182958447
0.00016560735047205894
If I call query
User.where("points > ?", 0.6238564767774734).count + 1
It returns 2. Why is that, shouldn't it return 0 as there are no values that are bigger than it? Also, queries with fourth and fifth values both return value of 5.
SQL queries from console as follows:
SELECT `users`.* FROM `users` WHERE (points > 0.623856)
SELECT `users`.* FROM `users` WHERE (points > 0.00935025)
SELECT `users`.* FROM `users` WHERE (points > 0.0016196)
Just in case I also tried length and size instead of count.
What is wrong and how I could I fix it? All help appreciated.
It looks like a problem with difference between that how mysql rounds floats and how ruby rounds floats. Using decimal instead of float might be a better idea.
Also take a look at
http://dev.mysql.com/doc/refman/5.0/en/floating-point-types.html
0.6238564767774734 goes beyond the precision of a float.
What you'd get in Postgres (I'm unaware of a pg_typeof() equivalent in MySQL):
denis=# select pg_typeof(0.6238564767774734);
pg_typeof
-----------
numeric
(1 row)
denis=# select 0.6238564767774734::decimal, 0.6238564767774734::float;
numeric | float8
--------------------+-------------------
0.6238564767774734 | 0.623856476777473
(1 row)
On its end, Ruby is using a BigDecimal. The MySQL type that would match it (more or less in MySQL, since you need to specify the precision) would be the decimal type:
http://dev.mysql.com/doc/refman/5.7/en/fixed-point-types.html
Be wary that MySQL requires a precision in this case:
mysql> select cast(0.6238564767774734 as decimal);
+-------------------------------------+
| cast(0.6238564767774734 as decimal) |
+-------------------------------------+
| 1 |
+-------------------------------------+
1 row in set (0.00 sec)
mysql> select cast(0.6238564767774734 as decimal(20,20));
+--------------------------------------------+
| cast(0.6238564767774734 as decimal(20,20)) |
+--------------------------------------------+
| 0.62385647677747340000 |
+--------------------------------------------+
1 row in set (0.00 sec)
Lastly, note that you'll still get errors due to rounding problems related to how floating point types are represented, if you stick to floats and adjust your criteria:
http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding
(I'm guessing you're using decimals internally in there somewhere, but the above set of problems related to floats are good to have in mind when doing comparisons.)