How do you round floats conditionally? - mysql

I am writing a query that is used by report generating software.
Part of this is querying for the hours needed to complete a project. We record this a 2 decimal float so that we can estimate to the quarter hour.
However, if we are using it in our report and the hour we recorded is something like 8.00, I want to query it and format it so that 8.00 is just 8. However any hours with something past the decimal, like 8.25, should remain as 8.25. How can I make this work?
hours Queried Result
====== -> My Query -> ==============
8.00 8
8.25 8.25
I am using MySQL 5.6

You can use the REPLACE() function to remove .00:
REPLACE(hours, '.00', '') AS hours

You can convert it to a string and check the rightmost 2 characters and trim those if they are '00'.
SELECT TRIM(TRAILING '.00' FROM CAST(column_name AS VARCHAR));

SELECT REPLACE(Round(8.00), '.00', ' ');
I will give more example so you can clear your Logic:
MySQL ROUND() rounds a number specified as an argument up to a number specified as another argument.
Syntax:
ROUND(N,[D]);
Where 'N' is rounded up to D decimal places.
and 'D' is indicating up to how many decimal places N will be rounded.
Example 1:-
SELECT ROUND(4.43);
Output :-
4
The above MySQL statement will round the given number 4.43. No decimal places have been defined, so the default decimal value is 0.
Example 2:-
SELECT ROUND(-4.53);
Output:-
-5
The above MySQL statement will round the given number -4.53. No decimal places have been defined, so the default decimal value is 0.

Related

Why is MySQL rounding division of 2 decimal to an unexcepted value?

I have a table with the following data:
Area VARCHAR(50),
Revenue DECIMAL(20,2),
Expense DECIMAL(20,2),
PercentBilled DECIMAL(6,2)
These values were imported from a spreadsheet and the percent billed is not precise enough. It's rounded to 2 decimal places. I can calculate it by taking Revenue / Expense, but I'm not getting the value I'm expecting.
Select * from would return 'Counter', -1822.90, 2749.63, 0.66
-1822.90 / 2749.63 = -0.6629619.... which the absolute value would round to 66.3%, which is the precision I need.
So why then, when I run the following query:
Select Area, (Revenue / Expense) AS calcPercentBilled, PercentBilled from
I get: 'Counter, -1822.90, 2749.63, 1.000000, 0.66 ?
My guess is it's something funky with MySQL and types, but I can't figure out what's happening. Why is MySQL rounding the division of 2 decimal numbers in a query to 1.000000?
The problem is the data type you have specified for PercentBilled.
DECIMAL(6,2) means store the value with 6 digits with 2 of them after the decimal point. So to increase the precision of the value stored you'll need to change the type of the column, perhaps to DECIMAL(9,6). This would allow the value in your example to be stored as "0.662962" (i.e. six decimal places).
Note that simply updating the type of the column will not magic up the missing precision unless you re-import your data from source. Simply changing the data type without re-loading the data will change it to "0.660000".

MariaDB SQL query returns truncated numbers from select statement

I am trying to pull data from Maria DB. The datatype in schema is DECIMAL (12, 8).
In my program when I query using following query. it trucates to 4 (or 3) decimal places and also round off.
select CAST(FORMAT(latitude, 100) AS FLOAT) latitude from mytable
it returns 36.173 . In DB it is stored as 36.17298200
I want it to return as 36.172982
To use the number in calculations, simply use it. No conversion, no CAST.
To dislay it to 6 decimal places, do that on SELECTing:
SELECT FORMAT(latitude, 6) ...
FORMAT(..., 100) should give you lots of decimal places.
FLOAT does not have enough precision to distinguish more than 6 or 7 significant decimal places. That is, the first and third numbers nere are the closest representable numbers in FLOAT:
x4210b122 --> 36.172981262207
36.17298200
x4210b123 --> 36.172985076904
Double:
x40421624463065f9 --> 36.1729819999999975
For Latitude and Longitude:
FLOAT has a resolution of 1.7 m or 5.6 ft -- good enough for Vehicles
DECIMAL(8,6) 16 cm 1/2 ft -- Friends in a mall
According to official MySQL documents:
The DECIMAL and NUMERIC types store exact numeric data values. These types are used when it is important to preserve exact precision, for example with monetary data. In MySQL, NUMERIC is implemented as DECIMAL, so the following remarks about DECIMAL apply equally to NUMERIC.
Floating-Point Types (Approximate Value) - FLOAT, DOUBLE
So you should be writing something similar to:
select CAST(FORMAT(latitude, 100) AS DECIMAL(8,6)) latitude from mytable
As 8 is the total number of digits and 6 is precision.

Column type for saving very different number of decimals

I need to store numbers like
21000
1.0002
0.00230235
12323235
0.2349523
This is sensordata so it is important to keep the exact value.
THere are many options.
My solution would be to multiply all values by 1 million, and store them as a bigint. Would that make sense?
That makes sense but I'd recommend that you just use the decimal datatype: https://dev.mysql.com/doc/refman/5.7/en/precision-math-decimal-characteristics.html
If you were to multiply by million and if a dataset you receive has one more decimal than you'd expect, you'd end up multiplying that number by 10 million and all other numbers by 10. Instead, using the decimal datatype will give you 30 numbers to the right of the decimal.
The declaration syntax for a DECIMAL column is DECIMAL(M,D). The
ranges of values for the arguments in MySQL 5.7 are as follows:
M is the maximum number of digits (the precision). It has a range of 1
to 65.
D is the number of digits to the right of the decimal point (the
scale). It has a range of 0 to 30 and must be no larger than M.
and
The SQL standard requires that the precision of NUMERIC(M,D) be
exactly M digits. For DECIMAL(M,D), the standard requires a precision
of at least M digits but permits more. In MySQL, DECIMAL(M,D) and
NUMERIC(M,D) are the same, and both have a precision of exactly M
digits.
For a full explanation of the internal format of DECIMAL values, see
the file strings/decimal.c in a MySQL source distribution. The format
is explained (with an example) in the decimal2bin() function.
To format your numbers, you could do formatting like this answer describes: Format number to 2 decimal places
Example
create table test (
price decimal(40,20)
);
-- all the above insertions will succeed cleanly
insert into test values (1.5), (1.66), (1.777), (1.12345678901234567890);
-- notice we have 21 digits after decimal
-- MySQL will insert data with 20 decimal and add a warning regarding data truncation
insert into test values (1.123456789012345678901);
Data
select * from test
price
1.50000000000000000000
1.66000000000000000000
1.77700000000000000000
1.12345678901234567890
1.12345678901234567890
select cast(price as decimal(40,2)) from test
price
1.50
1.66
1.78
1.12
1.12

MySQL ROUND() calculates incorrectly

I am having the problem with MySQL ROUND() Function.
Here it is:
When I do this:
SELECT ROUND(7/2) as avg FROM bla blah
avg is 4
When I do this:
SELECT ROUND(SUM(marks)/COUNT(marks)) as avg
avg is 3
Note: SUM(marks) on its own gives 7 and COUNT(marks) gives 2 which as far as I understand
ROUND(SUM(marks)/COUNT(marks)) should be equal to ROUND(7/2)
What is the problem?
Apparently MySQL interprets 7/2 as 7.0/2.0 and does the calculation using floating point numbers instead of integers, giving the result 3.5 rather than 3.
When you use sum the data type of the result is the same as the field, so you will be doing the calculation using integers, i.e. 7/2, giving the result 3.
Cast the values to double before doing the calculation:
SELECT ROUND(cast(SUM(marks) as double)/cast(COUNT(marks) as double)) as avg
You might use CEILING (same as ROUND except it always rounds to the bigger nearest integer)
SELECT CEILING(SUM(marks)/COUNT(marks)) as avg
should yield the result you want for the requirements specified in the question.
MySql mathematical operations create float results.
When using floats 7/2 could be represented as 3.4999999999999. Rounding that yields 3.

What does the first argument to MySQL's Decimal function do?

Using MySQL 5.0.27
This query:
SELECT CAST('543.21' AS DECIMAL(100,2))
returns 543.21
So does this one:
SELECT CAST('543.21' AS DECIMAL(2,2))
In fact, I am having trouble figuring out what effect the parameter has. I am using it to aggregate numeric values in a varchar column (for legacy reasons!!) and round off to 2 decimal places.
Should I just pick a high number?
It describes how many total digits a field (or variable) will be able to store.
DECIMAL(100,2) - 100 total digits, 98 before, 2 after a decimal separator
DECIMAL(2,2) 2 total digits, 0 before, 2 after a decimal separator
Explained here:
http://dev.mysql.com/doc/refman/5.1/en/numeric-types.html
[added]
For rounding just use ROUND() function.