Cast as decimal in mysql - mysql

I have below table structure and data :
create table sample
(
id INT(10)
);
INSERT INTO sample
values
(23398),
(98743),
(54734);
Now I want to understand CAST function in mysql. Consider following query :
select
cast((id/3) as decimal(2,2)) as cast1,
cast((id/3) as decimal(3,2)) as cast2,
cast((id/3) as decimal(4,2)) as cast3,
cast((id/3) as decimal(5,2)) as cast4,
cast((id/3) as decimal(6,2)) as cast5,
cast((id/3) as decimal(7,2)) as cast6,
id/3 as actualId
from sample;
Please see output of this query at SQL Fiddle.
I am wondering why this query gives 0.99, 9.99 and vice versa.
Can anyone explain it ?
Thanks in advance.

decimal is a type that takes 2 arguments
decimal(size, places) :
size determines how many digits are in the number.
places determines how many of those digits are to the right of the decimal.
decimal(2,2) - .00 - 2 digits both of which are to the right of the decimal
when casting (23398 / 3) = 7799.33333333 to declimal(2, 2) it yields a decimal in the specified amount of space closest to the desired number which is 0.99
decimal(3,2) - 0.00 - 3 digits 2 of which are to the right of the decimal
when casting (23398 / 3) = 7799.33333333 to declimal(3, 2) it yields a decimal in the specified amount of space closest to the desired number which is 9.99
if all of the original numbers were negative you would yield -0.99 and -9.99 because they are the closest numbers to the desired number within the allocated space
As a matter of fact java does something similar if you take the max double and try to convert it to an int you will give the max int which is no where near the max double

Related

MySQL ERROR 1264 (22003): Out of range value for column

I get this error:
ERROR 1264 (22003): Out of range value for column 'median_comments' at
row 1
after running this query:
update influencers set `median_comments` = 1347 WHERE `id` = 1;
I'm not sure why this fails on this number which doesn't have any decimals and which is only 4 digits.
The field type is:
median_comments decimal(10,8)
You are using DECIMAL(10,8) that means max digits before decimal would be (10 - 8) = 2.
Reference: DECIMAL Data Type Characteristics
The declaration syntax for a DECIMAL column is DECIMAL(M,D). The ranges of values for the arguments 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.
To fix the error, change your datatype to DECIMAL(10,2).
ALTER TABLE `influencers`
CHANGE COLUMN `median_comments` `median_comments` DECIMAL(10,2) NOT NULL DEFAULT 0;
If you are using decimal(10,8) as data type it means you are specifying 8 digits after decimal place which leaves only (10 - 8 i.e 2 digits) for your whole number.
In this case since your number 1347 contains 4 digits (whole number) hence you are getting the error as "Out of range value" since you are allowed only 2.
You should consider changing it to at least decimal (12,8) which will leave you 4 digits for your whole number part and your above command should work.
Please refer to post - Number format issue in Oracle. Same issue.
As you like me came here from google and your issue is related to Doctrine, and your column type is type="decimal", then you should configure precision and scale properties of your column in the right way.
For me, it was like before:
/** #ORM\Column(name="revenue", type="decimal", scale=4, nullable=true) */
private $revenue;
after
/** #ORM\Column(name="revenue", type="decimal", precision=14, scale=4, nullable=true) */
private $revenue;
It will be converted to DECIMAL(14,4), which means fourteen digits total, four of which are to the right of the decimal point.
Don't forget to prepare migration and run it to apply the changes.
Finally, you should get SQL like this:
ALTER TABLE project_finance CHANGE revenue revenue NUMERIC(14, 4) DEFAULT NULL

How to bitshift negative numbers with mySQL to get results like in Java, Python etc?

When i want to bitshift -2 >> 4 it should give me -1. python and java do give me -1. But if i try it on my mySQL server i get 1152921504606846975. I tryed to inverse the bits to cast it etc But i am not able to get a -1. So does someone know how to bitshift it to get -1.
According to the documentation, MySQL's bit shift operators generate an unsigned 64-bit integer. Therefore, if you want to get the expected behavior with negative numbers, you may add your own logic:
WITH yourTable AS (
SELECT 4 AS val UNION ALL
SELECT -4
)
SELECT
IF(val > 0, val >> 2, -1.0*((-1.0*val) >> 2)) AS result
FROM yourTable;
This outputs:
1
-1.0
>>:
Shifts a longlong (BIGINT) number to the right.
The result is an unsigned 64-bit integer. The value is truncated to 64 bits. In particular, if the shift count is greater or equal to the width of an unsigned 64-bit number, the result is zero.
-1 does not belong to the range of unsigned integer.

Get values from database with only 2 decimal places using MySQL

I want to retrieve values from a table with figures formatted in float. The decimal places range up to thirteen. I only want to retrieve the rows whose values only have exactly 2 decimal places. How do I do this?
Expected output:
[45.678, 56.236656457, 89.23, 100.89] ==> [89.23, 100.89]
You can use select Length(123.12 % 1) - 2 to get the length of the values after the decimal.
select (123.12 % 1) returns 0.12 so you always know that you have 0. in your result set, you can then get the length of your value minus the two characters and only select the rows where length = 2.

Out of range decimal type Mysql?

I need to store int and floating values numbers in field.
I use this type for field: decimal(5,4).
When I tried to store number 10 I got an error: Out of range decimal.
Why, if decimal(5,4) allows 5 position before dot and 4 positions after?
In the decimal(x, y) format, the x stands for the total number of digits, and y for the number of digits after the decimal place (. or ,). If assuming you want to store numbers up to 4 digits long (1000) with a precision of 2 (0.01) you'd need to use decimal(6, 2).
You are misunderstanding. decimal(5, 4) has 5 total digits of precision with 4 digits of scale after the decimal place. Hence, one is before.
You seem to want decimal(9, 4).

Anomalous mysql behaviour on replace query

im using a v simple database and i have 3 columns A(bigINT 20) , B(bigInt 20) and c(DECIMAL(5,4)) , when i fire the following query i get the below mentioned results :
REPLACE INTO `my_table` SET `A` = 8,`B` = 44,`C` = 14;
i get these values in mysql A =8 , b= 44 and c as 9.9999 ! ?
any ideas as to why is this happening and what can i do to resolved this ?
DECIMAL(5,4) means that the number has at most 5 digits, 4 of them after decimal point. So 14 is simply overflow as it would require DECIMAL(6,4).
It must be cleared that 14 is overflow, because as constant precision point decimal it is internally 14.0000 here (so six digits over five).
So if you try to put 14.0000 (six digits) in DECIMAL(5,4) (five digits max) -> MySQL chooses value closest to the one you request. Therefore 14.0000 gets "rounded" to 9.9999.
To fit 14 in your column you can either extend it do DECIMAL(6,4) (to allow more digits in general) or change to DECIMAL(5,3) (which will allow one more digit before decimal point, but loses some precision of course).