How to display two digits after decimal point in SQL Server - sql-server

I have table which has a column of float data type in SQL Server
I want to return my float datatype column value with 2 decimal places.
for ex: if i insert 12.3,it should return 12.30
if i insert 12,it should return 12.00

select cast(your_float_column as decimal(10,2))
from your_table
decimal(10,2) means you can have a decimal number with a maximal total precision of 10 digits. 2 of them after the decimal point and 8 before.
The biggest possible number would be 99999999.99

You can also do something much shorter:
SELECT FORMAT(2.3332232,'N2')

You can also use below code which helps me:
select convert(numeric(10,2), column_name) as Total from TABLE_NAME
where Total is alias of the field you want.

You can also Make use of the Following if you want to Cast and Round as well. That may help you or someone else.
SELECT CAST(ROUND(Column_Name, 2) AS DECIMAL(10,2), Name FROM Table_Name

select cast(56.66823 as decimal(10,2))
This returns 56.67.

Related

T-SQL Not Performing Arithmetic Calculation of Aggregates Correctly

I have a table variable that stores the average times for two separate sub tasks that is grouped by employee. I need to add a record that stores the calculated weighted averages for those two tasks for the entire company.
I added a column that stores the average times it took each employee to commit each subtask and then multiplied it by the number of total tasks that employee performed.
I populate the table with the records for each employee through the following query:
DECLARE #TotalNumberTasks INT
,#CompanyName VARCHAR(50) = 'Company ABC'
SELECT #TotalNumberTasks = COUNT(*) FROM Tbl1 --2436
INSERT INTO #OutputTemp
(
EmployeeID
,EmployeeName
,AverageTimeSubTask1
,AverageTimeSubTask2
,NumberTasks
,SqlComputedSubTask1WeightedNumber
,SqlComputedSubTask2WeightedNumber
)
SELECT TaskPerformedByUserID
,TaskPerformedByUserName
,AVG(CAST(SubTask1Time AS DECIMAL(6,2)))
,AVG(CAST(SubTask2Time AS DECIMAL(6,2)))
,COUNT(*)
,AVG(CAST(SubTask1Time AS DECIMAL(6,2))) * COUNT(*)
,AVG(CAST(SubTask2Time AS DECIMAL(6,2))) * COUNT(*)
FROM Tbl1
GROUP BY TaskPerformedByUserID, TaskPerformedByUserName
Once I have that information I use the following query to add the desired company aggregate row:
INSERT INTO #OutputTemp
(
EmployeeID
,EmployeeName
,AverageTimeSubTask1
,AverageTimeSubTask2
)
SELECT NULL
,#CompanyName
,SUM(CAST(SqlComputedSubTask1WeightedNumber AS DECIMAL(6,2)))/#TotalNumberTasks
,SUM(CAST(SqlComputedSubTask2WeightedNumber AS DECIMAL(6,2)))/#TotalNumberTasks
FROM #OutputTemp
The issue I'm facing is that the weighted value for each employee to get the company averages is being incorrectly calculated. I included two additional columns in the following example table structure example showing the correct values.
I'm mystified as to why this is happening. I understand that the division will result in the loss of information after the decimal when each number is rounded down but that's ok. The issue is it's not rounding down to the correct integer in some cases.
Furthermore, the calculations aren't even being made consistently. For example, on the record for Employee1, the same exact calculation is being performed (.06*145) and it results in two seperate values of 7 and 8.
I looked around and thought the issue may be related to this post, but when I tried converting the denominator to a float type as suggested I got the exact same results.
Any help greatly appreciated.
EDIT:
Here is the initial table variable declaration for #OutputTemp I was using:
DECLARE #OutputTemp TABLE
(
EmployeeID INT
,EmployeeName VARCHAR(75)
,AverageTimeSubTask1 DECIMAL(6,2)
,AverageTimeSubTask2 DECIMAL(6,2)
,NumberTasks INT
,SqlComputedSubTask1WeightedNumber INT
,SqlComputedSubTask2WeightedNumber INT
)
Here is the modified table variable structure that clarified the issue.
DECLARE #OutputTemp TABLE
(
EmployeeID INT
,EmployeeName VARCHAR(75)
,AverageTimeSubTask1 DECIMAL(10,8)
,AverageTimeSubTask2 DECIMAL(10,8)
,NumberTasks INT
,SqlComputedSubTask1WeightedNumber INT
,SqlComputedSubTask2WeightedNumber INT
)
Because I was using a type definition for AverageTimeSubTask1 & AverageTimeSubTask2 that was limiting the scale of the value to two decimal places, I was mistaking the value in the temp variable as what was used in the calculation, as mentioned by #WolfgangKais.
Here is the resulting #OutputTemp structure after changing the precision & scale for the two average sub task times:
As you can see, the calculations are indeed being performed correctly.
To start with, before getting deeper into troubleshooting, I would do ensure that no nulls are interfering with my dataset and only quality data is being processed:
In INSERT INTO #OutputTemp query add this condition in select : WHERE Employee is Not Null
Also, I would declare #OutputTemp table beforehand with appropriate column types so that I don't have to cast values last minute.
1) just have one end as decimal(14,4) for example, count returns INT which is lower in type precedence and SQL will do a cast up to decimal to match to the highest type.
2) Float and Real are not precise types, so you'll never get as accurate as decimal with at least 4 decimals as I suggested in my previous point.
Try this:
SELECT TaskPerformedByUserID
,TaskPerformedByUserName
,cast(COUNT(*) as decimal(14,4))/(select count(*) from Tbl1) * 100 percent_to_total
FROM Tbl1
GROUP BY TaskPerformedByUserID, TaskPerformedByUserName

CAST or convert Numeric to Money without rounding in SQL server

I want to convert numeric value to Money but without Rounding value.W.r.t. to
Link : https://technet.microsoft.com/en-us/library/ms187928(v=sql.105).aspx It is rounding numeric to Money while casting.
But is it possible to give value upto 4 digit after decimal.
NUMERIC VALUE : 123456789.3333
MONEY VALUE OUTPUT required : 123,456,789.3333
May be you are looking for something like this
SELECT FORMAT(CONVERT(MONEY, CAST(123456789.3333 AS NUMERIC(18,4))), '###,###.####')
Result
123,456,789.3333
I guess you mean numerics where you have more than 4 digits, then you could use ROUND:
SELECT CAST(ROUND(123456789.33339, 4, 1) AS MONEY)
-- 123456789,3333
vs.
SELECT CAST(123456789.33339 AS MONEY)
-- 123456789,3334
Rextester Demo
if you wanna split number as 3 digit , you can use this code in your select command
Select LEFT(CONVERT(VARCHAR, CAST(YourPrice AS MONEY), 1), LEN(CONVERT(VARCHAR, CAST(UnitPrice AS MONEY), 1)) - 3 )as UnitPrice

Having clause not working as expected

I have following statement
select pkid
from AttendancePosting
where datename(dw,AttDate) = 'Sunday' and empid=4 and attdate='2015-12-13'
group by PKId,timeout
--having 9=9
having cast(sum((datepart(minute, timeout)))/2 as float )+''=cast(datepart(minute,timeout) as float) +''
The problem is
having cast(sum((datepart(minute, timeout)))/2 as float )+''=cast(datepart(minute,timeout) as float) +''
Not working. both cast(sum((datepart(minute, timeout)))/2 as float ) and cast(datepart(minute,timeout) as float) bring the same value but still the select statement is not fetching any records, both returns 9
I have checked it like this
select pkid
from AttendancePosting
where datename(dw,AttDate) = 'Sunday' and empid=4 and attdate='2015-12-13'
group by PKId,timeout
having 9=9
And its bringing records, Any help will be appreciated.
First, your statement datepart(minute, timeout)/2 is going to return an integer. You can make SQL Server get more precise by being more precise like this datepart(minute, timeout)/2..
Second, floating point numbers are an approximation. You would do better to use ROUND() and specify the number of decimal places you think is appropriate. For example: round(sum((datepart(minute, timeout)))/2.0, 3).

How to get the sum of a row, whose datatype is varchar and its first character is "£"?

I want sum of the row whose datatype is varchar & first character is £ like :
Total
£23.0
£13.0
£2.40
I am using this query:
select sum(cast(SUBSTRING(total,2,(LEN(total)))as int)) as Total from tbl_preorder
Your query doesn't work due to decimal digits and field length. Try this:
SELECT Sum(Cast(Replace(total, '£', '') AS DECIMAL(10, 2)))
FROM test
WHERE total LIKE '£%'
and verify on SQL Fiddle
You can also use the slightly more concise.
SELECT SUM(CAST(total AS MONEY))
FROM tbl_preorder
SQL Fiddle
SELECT sum(cast(stuff(total, 1,1,'') as decimal(10,2))) as Total
FROM tbl_preorder
You should consider that you really want to do this. If you have possibility, you should change the data type of that column to decimal, or maybe introduce a computed column (which either would be this value with string, or will be a decimal and do the substring on varchar column).
hi hope this help thanks
SELECT SUM(CONVERT(DECIMAL(18,2), STUFF(total,1,1,''))) as Total from tbl_preorder
Hi Use below query, with same sequence as you mentioned above except datatype int to decimal.
SELECT sum(cast(SUBSTRING(total, 2, ( LEN(total) ))AS DECIMAL(10, 2))) AS Total
FROM tbl_preorder

Returning the result of divided number with a Scale in a Select Statement

I am trying to run this query, but it seems like it's not formatting the numbers properly after doing a mathematical calculation. The scale should be at 2, but it won't display as it should.
SELECT 30 / 60 as Diff FROM Table
This returns as 0
SELECT Convert( Numeric(8,2), 30 / 60 ) as Diff FROM Table
This returns as 0.00
How do I get this to return 0.50 as needed?
You can try the following and there are few ways to achieve it. Using a variable, or just performing CAST, CONVERT on the fields itself.
SELECT (CAST(30 AS DECIMAL(8,2)) / CAST(60 AS DECIMAL(8,2))) as Diff FROM Table
SELECT (CAST(30/60) AS DECIMAL(8,2)) as Diff FROM Table
SELECT (30/60.0) as Diff FROM Table;
SELECT CONVERT(DECIMAL(8,2), 30/60.0) as Diff FROM Table
Please take a look at this MSDN article for further reference:
Convert to numeric before doing the division or divide real numbers instead of integers. When doing integer arithmetic any decimal fraction is dropped. Converting after the fraction has been dropped doesn't do you any good.
SELECT CONVERT(NUMERIC(8,2),30.0/60.0) AS DIFF FROM TABLE
or if selecting columns instead of using numbers
SELECT CONVERT(NUMERIC(8,2),columnA)/CONVERT(NUMERIC(8,2),columnB) AS DIFF FROM TABLE
(converting both just to be sure the division is done according to the rules we want)

Resources