I've stumbled into an issue to get this code to show results with only 2 decimals
SELECT
SUM(CAST(
Size * 8 as Decimal)/1024
) as [Size in MB]
FROM
sysfiles
As for now it returns the size of my database with 7 decimals :/
I would advise converting to a decimal format with two places:
select convert(decimal(20, 2), size * 8.0/1024) as [Size in MB]
from sysfiles;
This converts the value to the right type. However, if you want to ensure that the value is displayed to the right precision/scale, then you can use format() or str():
select str(size * 8.0/1024, 20, 2) as [Size in MB]
from sysfiles;
You can cast decimal with just cast(xxx as decimal({length},{precision}))
SELECT
SUM(CAST(
Size * 8 as Decimal(20,2))/1024
) as [Size in MB]
FROM
sysfiles
just cast the sum itself to decimal
SELECT CAST(SUM(CAST(Size * 8 AS DECIMAL(18,2)) / 1024) AS DECIMAL(18,2)) [Size in MB]
Related
Code :
days_between("Created Time","Locked Time")*24
Result table :
Avg Response time (Hours)
2.91
6.00
9.13
3.65
1.17
0.00
0.77
32.47
The table above is the result i get after the code but currenlty I want to remove all decimal place right before i get this result with the days_between("Created Time","Locked Time")*24 i am using, So how can I do this. I tried to use cast and round () but is not working. Can someone help out. Thank you
Try code:
days_between("Created Time","Locked Time")*24 , 0) AS INT ) AS Response_Time
According to your sample data I guess:
with t(d) as (
values (2.91), (6.00), (9.13), (3.65), (1.17), (0.00), (0.77), (32.47)
)
select d, cast(d/24 as decimal(5,2)) from t;
I have a similar query running on MSSQL, and I can do it as:
SELECT TOP 10 a.SizeBytes AS originalValue
,COALESCE(a.SizeBytes, 0.00) / (1024 * 1024) AS defaultOperation
,CAST(COALESCE(a.SizeBytes, 0.00) / (1024 * 1024) AS INT) AS withCast
,FLOOR(COALESCE(a.SizeBytes, 0.00) / (1024 * 1024)) AS withFloor
,ROUND(COALESCE(a.SizeBytes, 0.00) / (1024 * 1024), 0) AS withRound
FROM filesUploaded a
WHERE a.SizeBytes > 0
Resulting in:
Note that I limited my query to the top 10, for speed generating this example, as my table contains millions of rows.
Also my starting value is integer, so I had to add the decimals in order to be able to see decimals. Probably you don't need to do that as the average should already have decimals, but in my case just dividing returned an integer result for the division without using the COALESCE before dividing.
anyone can try this in MsSQL:
select floor(4.7000000000000000000000000000000000000)+0.5
I get this result: 5 (!!) But should be 4.5 !?
Or try again with:
select floor(4.70 * 0.25000 * 0.2440 * 5.6325 * 3.0542 * 2.345 * 2.35 * 3.253 )+0.5
The result is 89!! But should be: 88.5 ?!
Is this an issue? Or is there an explanation about that?
(the same problem with CEILING)
Thank you all!
Per the documentation of FLOOR:
-- Syntax for SQL Server, Azure SQL Data Warehouse, Parallel Data Warehouse
FLOOR ( numeric_expression )
Return Types
Returns the same type as numeric_expression.
The problem with this is that it's not true. It preserves the base type, but in case of a decimal type, the scale is reduced to 0:
SELECT
SQL_VARIANT_PROPERTY(4.00, 'precision') AS [precision]
SQL_VARIANT_PROPERTY(4.00, 'scale') AS scale,
Result: precision 3, scale 2.
SELECT
SQL_VARIANT_PROPERTY(FLOOR(4.00), 'precision') AS [precision],
SQL_VARIANT_PROPERTY(FLOOR(4.00), 'scale') AS scale
Result: precision 3, scale 0. This becomes a problem as soon as your decimal hits the maximum precision:
SELECT
SQL_VARIANT_PROPERTY(4.7000000000000000000000000000000000000, 'precision') AS [precision]
SQL_VARIANT_PROPERTY(4.7000000000000000000000000000000000000, 'scale') AS scale,
Precision 38, scale 37. But FLOOR turns this into precision 38, scale 0, and
SELECT CONVERT(DECIMAL(38, 0), 4) + 0.5
results in 5, per the rules for precision and scale when adding decimals: the result of this should be a decimal(40, 1), but as that exceeds the maximum precision, the scale is reduced to preserve as many digits in front of the period as possible, giving us a decimal(38, 0) again: 5.
Conversely, there's no problem with this:
SELECT 4.0000000000000000000000000000000000000 + 0.5
The result of this is a DECIMAL(38, 37), which can hold 4.5000000000000000000000000000000000000 exactly.
The moral: be aware of this scale-eliminating aspect of FLOOR (and CEILING) and reduce the precision as necessary so the scale doesn't get reduced due to overflow:
SELECT CONVERT(DECIMAL(3, 0), FLOOR(4.70 * 0.25000 * 0.2440 * 5.6325 * 3.0542 * 2.345 * 2.35 * 3.253)) + 0.5
Yields 88.5.
The first line of code displays to 2 decimal points
The second line displays to 3 decimal points
SUM(CONVERT(DECIMAL(8,2),[can]/1.2)) + SUM(CONVERT(DECIMAL(8,2),[carton]/1.2)) AS [N],
(SUM(CONVERT(DECIMAL(8,2),[can]/1.2)) + SUM(CONVERT(DECIMAL(8,2),[carton]/1.2)))*0.2 AS [V]
Can someone please tell me how to get the second line to show 2 decimal points
If you want to control the display, the do the cast to decimal after the calculation:
CONVERT(DECIMAL(8, 2), SUM([can]/1.2)) + SUM([carton]/1.2)) AS [N],
You can do the conversion before, if you have a need to represent the some intermediate value as a decimal. Do note, though, that SQL Server has quite arcane rules for the precision and scale of intermediate and final results when doing decimal arithmetic.
Just cast the result to a 2 decimal place decimal:
select --just added to make the example runnable
SUM(CONVERT(DECIMAL(8,2),[can]/1.2)) + SUM(CONVERT(DECIMAL(8,2),[carton]/1.2)) AS [N],
CONVERT(DECIMAL(8,2), --add this line
(SUM(CONVERT(DECIMAL(8,2),[can]/1.2)) + SUM(CONVERT(DECIMAL(8,2),[carton]/1.2)))*0.2
) --and an additional close bracket
AS [V]
from (select 1.0 [can], 1.0 [carton] union all select 2.0, 3.0) x --just added to make the example runnable
The reason you're seeing 3 decimal places is because that's what the result of the calculation is; and when working with decimals SQL will output a decimal of the appropriate precision and scale to hold that result, unless you cast/convert it to something specific.
You convert to 2 decimals using CONVERT...
SELECT
SUM(CONVERT(decimal(8, 2), [can] / 1.2)) + SUM(CONVERT(decimal(8, 2), [carton] / 1.2)) AS [N],
CONVERT(decimal(8, 2), ((SUM(CONVERT(decimal(8, 2), [can] / 1.2)) + SUM(CONVERT(decimal(8, 2), [carton] / 1.2))) * 0.2)) AS [V]
I want to round of the values of two columns:
select a.region as "Regions",
a.suminsured,2 as "SumInsured" ,
a.suminsured/b.sum*100 as pct
from (
SELECT region, sum(suminsured) as suminsured
FROM "Exposure_commune" group by region
) a,
(select sum(suminsured) FROM "Exposure_commune") b
I want the suminsured and pct columns to come with 2 decimal places. Can someone tell me what I should do?
You can use directly numeric with two parameters. Second parameter for round decimal.
select sum(column_name::numeric(10,2)) from tablename
Use round() with two parameters, which only works for the data type numeric.
While being at it, your query can be simpler and faster:
SELECT region
, round(sum(suminsured), 2) AS suminsured
, round((sum(suminsured) * 100) / sum(sum(suminsured)) OVER (), 2) AS pct
FROM "Exposure_commune"
GROUP BY 1;
You can use sum() as window function to get the total without additional subquery, which is cheaper. Related:
Postgres window function and group by exception
Multiplying first is typically cheaper and more exact (although that barely matters with numeric).
Data type is not numeric
For data types double precision of real
You can ...
just cast to numeric to use the same function.
multiply by 100, cast to integer and divide by 100.0.
multiply by 100 and use the simple round() and devide by 100.
The simple round() with just one parameter works for floating point types as well.
Demonstrating all three variants:
SELECT region
, round(sum(suminsured), 2) AS suminsured
, (sum(suminsured) * 100)::int / 100.0 AS suminsured2
, round(sum(suminsured) * 100) / 100 AS suminsured3
, round((sum(suminsured) * 100) / sum(sum(suminsured)) OVER (), 2) AS pct
, ((sum(suminsured) * 10000) / sum(sum(suminsured)) OVER ())::int / 100.0 AS pct2
, round((sum(suminsured) * 10000) / sum(sum(suminsured)) OVER ()) / 100 AS pct3
FROM "Exposure_commune"
GROUP BY 1;
SQL Fiddle.
I'm working in SQL Server 2008. I have an alias column that I'm creating via the following formula:
col1 / col2 * some_number
col1 and col2 are nvarchars in my table, but they're really integers. some_number is an integer. If I blindly do col1 / col2, I will get 0 for most. So, I need to cast them as decimals. I want there to be a maximum of 2 decimal places after the decimal point. Here is what I have currently:
CAST(col1 AS DECIMAL(10,2)) / CAST(col2 AS DECIMAL(10,2)) * 100
However, this returns far more decimal places than just 2. How do I fix my code to return just 2 decimal places?
According to the documents the scale of the result is given by:
s2 = max(6, s1 + p2 + 1)
where p2 represents the precision of the numerator and s2 represents scale of the denominator
So when dividing one DECIMAL(10, 2) by another you can substitute in values:
s2 = max(6, 2 + 10 + 1) = 13
Which is corroborated with a simple example:
SELECT CAST(1 AS DECIMAL(10,2)) / CAST(1 AS DECIMAL(10,2))
= 1.0000000000000 -- 13 decimal points
You need to use another cast on your result to reduce the scale:
SELECT CAST(CAST(col1 AS DECIMAL(10,2)) / CAST(col2 AS DECIMAL(10,2)) * 100 AS DECIMAL(10, 2))
I'd also suggest if the data type of you column is nvarchar, "but they're really integers" that you just bite the bullet and alter the column data type.