I'm trying to figure out decimal data type of a column in the SQL Server. I need to be able to store values like 15.5, 26.9, 24.7, 9.8, etc
I assigned decimal(18, 0) to the column data type but this not allowing me to store these values.
What is the right way to do this?
DECIMAL(18,0) will allow 0 digits after the decimal point.
Use something like DECIMAL(18,4) instead that should do just fine!
That gives you a total of 18 digits, 4 of which after the decimal point (and 14 before the decimal point).
You should use is as follows:
DECIMAL(m,a)
m is the number of total digits your decimal can have.
a is the max number of digits you can have after the decimal point.
http://www.tsqltutorials.com/datatypes.php has descriptions for all the datatypes.
The settings for Decimal are its precision and scale or in normal language, how many digits can a number have and how many digits do you want to have to the right of the decimal point.
So if you put PI into a Decimal(18,0) it will be recorded as 3?
If you put PI into a Decimal(18,2) it will be recorded as 3.14?
If you put PI into Decimal(18,10) be recorded as 3.1415926535.
For most of the time, I use decimal(9,2) which takes the least storage (5 bytes) in sql decimal type.
Precision => Storage bytes
1 - 9 => 5
10-19 => 9
20-28 => 13
29-38 => 17
It can store from 0 up to 9 999 999.99 (7 digit infront + 2 digit behind decimal point = total 9 digit), which is big enough for most of the values.
You can try this
decimal(18,1)
The length of numbers should be totally 18. The length of numbers after the decimal point should be 1 only and not more than that.
In MySQL DB decimal(4,2) allows entering only a total of 4 digits. As you see in decimal(4,2), it means you can enter a total of 4 digits out of which two digits are meant for keeping after the decimal point.
So, if you enter 100.0 in MySQL database, it will show an error like "Out of Range Value for column".
So, you can enter in this range only: from 00.00 to 99.99.
The other answers are right. Assuming your examples reflect the full range of possibilities what you want is DECIMAL(3, 1). Or, DECIMAL(14, 1) will allow a total of 14 digits. It's your job to think about what's enough.
request.input("name", sql.Decimal, 155.33) // decimal(18, 0)
request.input("name", sql.Decimal(10), 155.33) // decimal(10, 0)
request.input("name", sql.Decimal(10, 2), 155.33) // decimal(10, 2)
Related
Projected code is used to convert a date into integer and vice-versa. I want to know the reason why here we have used this specific hexadecimal codes and the number series to get back the date from int. If there is an article about this code sample it would also help me understand this code actually.
I have tried online Hex to Decimal conversion for this codes and found its a 256^1,256^2... even though trying not able to find the exact reason.
declare #dDate date = '2017-10-12'
declare #iDate int = 0
select #iDate = ( (datepart(year,#dDate)*65536 | datepart(month,#dDate)*256 | datepart(dd,#dDate)))
select (#iDate&0xfff0000)/65536 --year
select (#iDate&0xff00)/256 --Month
select (#iDate&0xff) --Date
& is an operator doing bitwise AND. "|" is bitwise OR. See here and here. Also see here for an explanation on using bitwise AND/OR to store multiple number values in a single number column.
This part:
#iDate&0xfff0000
will "mask", or eliminate/replace-with-zeros, the portion of iDate that isn't from 256^2. Then you divide by 65536 -- which is simply reversing the original math of multiplying the year by 65536.
If the concept of bitwise AND is foreign, I'll give an example that DOESN'T WORK in decimal. Bitwise AND converts the whole thing to binary and then masks things (like IP subnetting, if you're familiar with that).
Anyway, consider a decimal number 20171012. If such a thing as a decimal-wise AND existed, it could look like 20171012&11110000. The "1" places are "keepers" and the "0" places are "throw-aways". If you stack them vertically, the result is to keep the values with a "1" beneath them and replace the values with a "0" beneath them with a "0".
number 20171012
dec-wise AND 11110000
result 20170000
now the result isn't 2017, so you'd have to divide by 10000 to get 2017.
For 20171012&1100 you have to use implied leading zeros:
number 20171012
dec-wise AND 00001100
result 1000
I probably would have converted to int by adding the year*10000 and month * 100 and day. Reverting back I would use a combination of integer division and MOD. But I think the bitwise AND is perhaps a bit more elegant (particularly for getting the month).
Based on your comment, I will include how I have converted dates to int and reverted back:
declare #dDate date = '2017-10-12'
declare #iDate int
set #iDate = year(#dDate) * 10000 + month(#dDate) * 100 + day(#dDate)
select #iDate
select 'year', #iDate/10000 -- basic integer division provides the year
select 'month', (#iDate % 10000)/100 -- combine modulo and integer division to get the month
select 'day', #iDate % 100 -- basic modulo arithmetic provides the day
returns:
20171012
year 2017
month 10
day 12
This is bit manipulation.
Bit Shifting
Decimal 3 = Binary 11
If we do a left shift (<<) 4 bits in 3 it will become 48 which is equal to binary 110000 <- 4 zero bits added due to left shift
But since we don't have bit shifting operators in T-SQL therefore we can do the math.
Left Shifting of n bits in number x = x * 2^n
Therefore, multiple a number with 256 is actually left shift 8 bits from that number (2^8 = 256).
Later on when you do bitwise OR between 2 numbers they actually "concatenate" the bits up.
For example, you need to concatenate 2 binary numbers, (3) 11 and (2) 10, the resultant number should be 1110 = 14
So first we'll do 2 left shift in 3 = 3 * 2^2 = 12 and then we will do bitwise OR this number with the next number
12 = 1100
2 = 0010
OR
---------------
14 = 1110
Your example is actually saving the whole date in an integer variable which is actually efficient way of saving a date.
I am currently outputting values out to 6 decimal places, and would like to round up the 6th place regardless of the integer value.
I have been using a CEILING() function so far which has worked great for values 1-9 on rounding up; however, in situations where I have the 7th decimal as 0 (ex: 2705.1520270), the function does not round up to 2705.152028.
select CEILING(price*1000000)/1000000 as PriceRound
from tc_alcf a (nolock)
Here is one approach:
SELECT ROUND(2705.1520270 + 0.0000005, 6);
2705.1520280
Demo
We can add 0.0000005 to the input and then just use SQL Server's ROUND function to 6 decimal places. This works because values with a sixth decimal place between 0 and 0.4999 (repeating) would become 5 to 0.9999 (repeating), meaning they would round up to the next digit. And values with already have 5 or greater in the sixth decimal place would not be bumped up to the next digit.
This problem should be familiar to many developers as the rounding half up problem.
Add 1 and use FLOOR():
select floor(price*1000000 + 1)/1000000 as PriceRound
from tc_alcf a
Or you can also shift the decimal by multiplying with the power function
CEILING(2705.1520275 * POWER(10,6)) / POWER(10,6)
I have columns RSL and SUMofRSL. I have tried calculating the percentage but it returns either 100% or 0%. In some instances it is a wrong calculation since it shows 0% . Below are the examples for your reference.
RSL SUMofRSL Percentage
------------------------------
2 2 100%
1 2 0%
48 96 0%
10 10 100%
I have used
([RSL] / [SumOfRSL]) * 100
Assuming the data types of RSL and SumOfRSL are integers you will need to cast the columns to a data type that supports decimal places.
For example:-
(CAST([RSL] AS DECIMAL(10, 4)) / CAST([SumOfRSL] AS DECIMAL(10, 4)))
The division of two Integer factors will be another Integer. At least one of your factors must be decimal type if you want that the result be decimal. (See this link)
You can CAST one or both of your values as Kane suggested.
I have a question about the format of numbers REAL.
I have a column with this type and after I insert 8 numbers for this column, it doesn't let me to save.
Example: 11406760
When I try with a 7 digit numbers like 1140676, it lets me to save the data.
Any idea why this happens?
If I read this MSDN page correctly, REAL is a synonym for FLOAT(24), which has a precision of 7 digits.
This means that while a column of this type does support values up to about 10^38, it only keeps about 7 most significant digits of that value. So for an 8 digit number, the final digit may not be stored correctly.
Do you really need a REAL (=floating point) value for this column (maybe check out decimal), or rather some integer type?
I am writing a custom totaling method for a grid view. I am totaling fairly large numbers so I'd like to use a decimal to get the total. The problem is I need to control the maximum length of the total number. To solve this problem I started using float but it doesn't seem to support large enough numbers, I get this in the totals column(1.551538E+07). So is there some formating string I can use in .ToString() to guarentee that I never get more then X characters in the total field? Keep in mind I'm totaling integers and decimals.
If you're fine with all numbers displaying in scientific notation, you could go with "E[numberOfDecimalPlaces]" as your format string.
For example, if you want to cap your strings at, say, 12 characters, then, accounting for the one character for the decimal point and five characters needed to display the exponential part, you could do:
Function FormatDecimal(ByVal value As Decimal) As String
If value >= 0D Then
Return value.ToString("E5")
Else
' negative sign eats up another character '
Return value.ToString("E4")
End If
End Function
Here's a simple demo of this function:
Dim d(5) As Decimal
d(0) = 1.203D
d(1) = 0D
d(2) = 1231234789.432412341239873D
d(3) = 33.3218403820498320498320498234D
d(4) = -0.314453908342094D
d(5) = 000032131231285432940D
For Each value As Decimal in d
Console.WriteLine(FormatDecimal(value))
Next
Output:
1.20300E+000
0.00000E+000
1.23123E+009
3.33218E+001
-3.1445E-001
3.21312E+016
You could use Decimal.Round, but I don't understand the exact question, it sounds like you're saying that if the total adds up to 12345.67, you might only want to show 4 digits and would then show 2345 or do you just mean that you want to remove the decimals?