Converting height and inches (with decimal) to inches - sql

I have a character based height field with some irregular entries. The most typical case is straightforward such as 6'3", or 5'11' (easy to convert). Unfortunately, we also have some entries with a decimal in the inches value such as 5'2.5" or 5'3.25".
My goal is to convert to an integer-based total inches, taking out the decimal, and rounding to the nearest inch.
Any helps?

First Get your feet (the number before the ') and multiply by 12, then get your inches (number between ' and ") ad round to the nearest whole number, add these numbers together and that's your height in inches :)
This query might help:
SELECT
CAST(SUBSTRING(your_column, 0, CHARINDEX ('''',your_column)) as INT)
* 12
+ ROUND(CAST(SUBSTRING(your_column,
CHARINDEX('''', your_column) + 1,
LEN(your_column) - CHARINDEX('''',your_column) - 1) as DECIMAL),0)
as Height

Related

SQLite - DB Browser

How can I use SQL to calculate Feet and inches from a column that gives the Height value?
Example
Height = 65
I need to transform into Feet and inches, by dividing 65/12 = 5 feet 42 inches.
I am new, so What is the function that I need to use?
Thanks
You can use division and modulo. Most SQL dialects have a concatenation function or operator:
select Concat(65/12, ' feet ', 65 % 12, ' inches')
5 feet 5 inches

numerical overflow

I have a field in my SQL database which has a data type of Decimal(2, 2). The problem is when I try to insert data i.e. 5 or -5 in this field I get database error (314) which is numerical overflow. I don't know why I'm getting that error.
DECIMAL(2, 2) only allows a range of -0.99 to 0.99
DECIMAL(X, Y)
X = Precision (Number of significant digits)
Y = Scale (Number of digits after decimal point)
For example DECIMAL(5, 2) would give the range between:
-999.99 to 999.99.
Decimal(2,2) commonly means "Two digits of significance, two digits to the right of the decimal point", meaning that such a field can contain value which range from 0 to .99, positive or negative. Thus, 5 is out of range for such a field.
If you wanted to store a single-digit integer such as 5 in a decimal field while also allowing up to two digits to the right of the decimal point you'd have to define the field as Decimal(3, 2), or in other words "Three total significant digits, two of them to the right of the decimal place".

How to write in vb.net a decimal number without rounding the 12 digits after the decimal point?

I try to write the result of the division of the number 5991 by 2987 in vb.net, without rounding the decimal or floating point, strictly equal to 2.005691329092 on 12 digits after the decimal point. The decimal part (0.05691329092) is also noted 17/2987 in scientific notation. My tests always led me to 2.005691329093 rounding!
2 17/2987
Actual value is correct, issue is how to format value to display it as expected.
There are no built-in method, but you can multiply value by required amount of digits after decimal point and truncate it.
Dim value As Double = 5991.0 / 2987.0
value = Math.Truncate(value * Math.Pow(10, 12)) / Math.Pow(10, 12)
Console.WriteLine($"Result: {value:F12}")

whats the best datatype to store height?

Pretty straight forward question, I want to store feet and inches in 1 column using a decimal, but I dont want it truncated like how the float type does.
Store all your data in MKS (metric). When presenting and storing convert the data into an international standard. and store it in a decimal type.
Thus if your tool to gather the data is in 6'2" format convert it into cm and save in your data table. Then reverse this for display.
By saving in a standard format decimal cm. finding people with the same range of height is easier, where as if Ft and In are in separate columns ranges are really hard.
The imperial unit system still used in Myanmar, Liberia and that one country in North America is unfortunately not very arithmetics-friendly. There is no native data-type to handle the strange base12/base3/base1860 math for it.
You should really use the much more widely-used metric system and use a FLOAT or DECIMAL value representing meters.
However, when you really want to stay with the imperial system, you should store the value in inch and do the conversation to feet + inch on the GUI level.
Decimal lets you store an exact precision.
The question is if you want to store it in feet or inches.
If inches then:
feet * 12 + inches
If feet then:
feet + (inches / 12)
If inches the conversion back
declare #inches dec(8,4)
declare #indesinfoot as dec(8,4);
set #indesinfoot = 12;
set #inches = (12*#indesinfoot) + 6.25;
print #inches;
SELECT cast(#inches/#indesinfoot as Int) as feet,
inches % #indesinfoot AS inches;
I would go with inches as you can get some rounding error with division but not with multiplication.
Use DECIMAL Data type
It lets you specify the precision you need for your specific needs, without truncating like FLOAT
NUMERIC() or DECIMAL() will work for a single column answer, but you'll need to decide if you're storing feet or inches. These fields use precise math and accurate storage.
If you must store feet and inches, you'll need to either define your own datatype (which is fairly complicated) or use two NUMERIC() or DECIMAL() fields.
Not that you'd ever run into precision problems with feet or inches with FLOAT when measuring something the size of a human being. You'd be off by a hair. Literally.
Example procedure to convert the old English system to metric. No error checking but it will give you an idea how to convert data as entered into data for storage.
CREATE PROCEDURE usp_ConvertHeight
#Input varchar(10)
AS
BEGIN
DECLARE
#FT AS DECIMAL(18,10) = 0,
#IN AS DECIMAL(18,10) = 0,
#CM AS DECIMAL(18,10)
SELECT #FT = CAST(left(#Input,CHARINDEX('''',#Input,1) - 1) AS DECIMAL(18,10));
SELECT #IN = CAST(REPLACE(SUBSTRING(#Input,CHARINDEX('''',#Input,1) + 1,10),'"','')AS DECIMAL(18,10));
SET #CM = 2.54 * ((12 * #FT) + #IN);
SELECT #CM
END
I suggest to store the data in single unit,either inches or in cm.
Ideally give the user option to enter it in any format. Convert and show the user information in all the possible units like in feets and inches and cm.

SQL Round Function

round(45.923,-1) gives a result of 50. Why is this? How it is calculated?
(sorry guys i was mistaken with earlier version of this question suggesting value was 46)
The SQL ROUND() function rounds a number to a precision...
For example:
round(45.65, 1) gives result = 45.7
round(45.65, -1) gives result = 50
because the precision in this case is calculated from the decimal point. If positive then it'll consider the right side number and round it upwards if it's >= 5, and if <=4 then round is downwards... and similarly if it's negative then the precision is calculated for the left hand side of decimal point... if it's >= 5
for example round(44.65, -1) gives 40
but round(45.65, -1) gives 50...
ROUND(748.58, -1) 750.00
the second parameter: Lenght, is the precision to which numeric_expression is to be rounded. length must be an expression of type tinyint, smallint, or int. When length is a positive number, numeric_expression is rounded to the number of decimal positions specified by length. When length is a negative number, numeric_expression is rounded on the left side of the decimal point, as specified by length.
From
It is expected to be 50.
round(45.923, 0) => 46
expl: the last non-decimal digit is rounded (5), the desicion is based on the next digit (9)
9 is in the high half, ergo 5 is rounded up to 6
round(45.923, 1) => 45.9
expl: the first decimal digit is rounded (9), the desicion is based on the next digit (2)
2 is in the low half, ergo 9 stays 9
your case:
round(45.923, 1-) => 45.92
expl: the secon-last non-decimal digit is rounded (4), the desicion is based on the next digit (5)
5 is in the top half, ergo 4 is rounded up to 5, the rest of the digist are filled with 0s
As for how, start by considering how you'd round a (positive) float to the nearest integer. Casting a float to an int truncates it. Adding 0.5 to a (positive) float will increment the integer portion precisely when we want to round up (when the decimal portion >= 0.5). This gives the following:
double round(double x) {
return (long long)(x + 0.5);
}
To add support for the precision parameter, note that (for e.g. round(123456.789, -3)) adding 500 and truncating in the thousands place is essentially the same as adding 0.5 and to rounding to the nearest integer, it's just that the decimal point is in a different position. To move the radix point around, we need left and right shift operations, which are equivalent to multiplying by the base raised to the shift amount. That is, 0x1234 >> 3 is the same as 0x1234 / 2**3 and 0x1234 * 2**-3 in base 2. In base 10:
123456.789 >> 3 == 123456.789 / 10**3 == 123456.789 * 10**-3 == 123.456789
For round(123456.789, -3), this means we can do the above multiplication to move the decimal point, add 0.5, truncate, then perform the opposite multiplication to move the decimal point back.
double round(double x, double p) {
return ((long long)((x * pow10(p))) + 0.5) * pow10(-p);
}
Rounding by adding 0.5 and truncating works fine for non-negative numbers, but it rounds the wrong way for negative numbers. There are a few solutions. If you have an efficient sign() function (which returns -1, 0 or 1, depending on whether a number is <0, ==0 or >0, respectively), you can:
double round(double x, double p) {
return ((long long)((x * pow10(p))) + sign(x) * 0.5) * pow10(-p);
}
If not, there's:
double round(double x, double p) {
if (x<0)
return - round(-x, p);
return ((long long)((x * pow10(p))) + 0.5) * pow10(-p);
}
It doesn't for me on MySQL:
mysql> select round(45.923,-1);
+------------------+
| round(45.923,-1) |
+------------------+
| 50 |
+------------------+
1 row in set (0.00 sec)
And on Sql Server 2005:
select round(45.923,-1)
------
50.000
What database are you running this on?
one thing is in the round function first parameter is the number and the second parameter is the precision index from the decimal side.
That means if precision index is 0 it is at the first decimal, -1 means before the decimal first number, 1 means right side of the first decimal i.e second decimal
For example
round(111.21,0)---------> return 111
round(115.21,-1)--------->return 120
round(111.325,2)---------->return 111.33
round(111.634,1)-----------> return 111.6