I have the following SQL query that comes out at 700
declare #a decimal(10,0)
declare #b decimal(10,0)
set #a = 100 - 2
set #a = #a / 14
set #a = #a * 100
set #a = ((100 - 2) / 14) * 100
select #a
What i am looking for it do is return 85.714285 etc...
Not quite sure where i going wrong.
Thanks
Your declaration is wrong:
declare #a decimal(10,0)
declare #b decimal(10,0)
You have specified the length, however not the number of decimals, which is done by using the second value.
700 is the correct result.
Please check again!
((100 - 2) / 14) * 100 = 700
You calculated that
100 - 2 / 14 * 100 = 85,...
You want to use this sql query.
set #a = 100 - 2.0 / 14 * 100
Add a .0 to the end of your last line, since if you use all integers SQL will implicitly cast the result as an int.
set #a = ((100 - 2) / 14) * 100.0
change your declarations to include decimal places:
declare #a decimal(10,5)
declare #b decimal(10,5)
set #a = 100 - 2
set #a = #a / 14
set #a = #a * 100
set #a = ((100 - 2) / 14) * 100
select #a
Since your declaration is set to 10,0 then you will get no decimal places.
if you want the answer to be 85.714... then you need to change your SQL to:
declare #a decimal(10,5)
set #a = 100.0 - 2.0
set #a = #a / 14.0
set #a = #a * 100.0
set #a = 100.0 - ((2.0 / 14.0) * 100.0)
select #a
To get the result you are looking for you need to add a . to the other values (2, 14, etc) and you will get the value you want, you also need to make sure that your parentheses are in the correct location.
Results - 85.71430
Related
Formula used
This is the formula that I used to calculate
Expressed as a single equation:
eGFR = 142 x min(Scr/κ, 1)α x max(Scr/κ, 1)-1.200 x 0.9938Age x 1.012 [if female]
where:
Scr = serum creatinine in mg/dL
κ = 0.7
α = -0.329
min(Scr/κ, 1) is the minimum of Scr/κ or 1.0
max(Scr/κ, 1) is the maximum of Scr/κ or 1.0
Age (years)
Code that I tried
select
ROUND(141 * power(min(cast(40 as float) / 0.7 ) ,-0.329) *
power(max( cast(40 as float) / 0.7 * 1) ,- 1.209) * 0.993 *
cast(42 as float) * 1.018 ,2) as kidney
Correct answer should be 123.
Any clue what I am missing in the query?
Don't use MIN and MAX, those are aggregate (GROUP BY) functions. It would be good if SQL Server had GREATEST and LEAST functions, but it doesn't yet.
IIF(a < b, a, b) is LEAST(a,b).
IIF(a > b, a, b) is GREATEST(a,b).
Don't sweat the CASTs.
Make no assumptions about operator precedence ( x before +, etc). Use parentheses.
Here's a rewrite of what I believe your formula should be. But I'm not getting the right answer yet either.
DECLARE #Scr AS INT = 40;
DECLARE #k AS FLOAT = 0.7;
DECLARE #a AS FLOAT = -0.329;
DECLARE #age AS INT = 42;
DECLARE #gender AS VARCHAR(MAX) = 'female';
DECLARE #factor AS FLOAT = CASE WHEN #gender = 'male' THEN 1.0 ELSE 1.012 END;
SELECT 142
+ (IIF(1 < #Scr/#k, 1, #Scr/#k) * #a)
* (IIF(1 > #Scr/#k, 1, #Scr/#k))
- (1.2 * 0.993 * #age * #factor);
I obviously misunderstood your formula, but this should get you started. Here's a fiddle.
According to this site your equation is kinda wrong. Please be sure to add ^ to display the "to the power of".
DECLARE #Scr AS FLOAT = 40.0;
DECLARE #gender AS VARCHAR(10) = 'female';
DECLARE #age AS SMALLINT = 42;
DECLARE #k AS FLOAT = CASE WHEN #gender = 'male' THEN 0.9 ELSE 0.7 END;
DECLARE #a AS FLOAT = CASE WHEN #gender = 'male' THEN -0.302 ELSE -0.241 END;
DECLARE #factor AS FLOAT = CASE WHEN #gender = 'male' THEN 1.000 ELSE 1.012 END;
SELECT 142 * POWER(IIF(1 < (#Scr/#k), 1, #Scr/#k), #a)
* POWER(IIF(1 > (#Scr/#k), 1, #Scr/#k), -1.200)
* POWER(0.9938, #age)
* #factor;
Also this result is correct since it is calculated in mg/dl and your expected value is in umol/l
Here is another website (it may be german, but it should do the trick)
I need to minimize the length of number to fixed value 3 with decimal point 1
Ex:
After calculation value of #a=45689.45.
Now I need to get value of #a =45.6
If the value is less then 100 i.e if it is 89.63 then I don't need to change it.
At last value of #a should be decimal of (3,1)
How about:
case when #a >= 100 then
round(#a / power(10, floor(log10(#a)) - 1), 1, 1)
else #a
end
Try this
DECLARE #a DECIMAL(7, 2)=45689.45
SELECT CASE
WHEN len(CONVERT(INT, #a)) > 3 THEN LEFT(#a / CONVERT(INT, '1' + replicate(0, len(CONVERT(INT, #a))-2)), 4)
ELSE #a
END
I haven't tested this to death but without using string manipulation this might do the job;
declare #i decimal(18, 6); set #i = 2000
select cast(round(#i / case when #i >= 100 then (power(10, floor(log10(#i)) - 1)) else 1.0 end, 1) as decimal(3,1)
Fingers crossed :)
Rhys
I'm writing a query, part of Stored Procedure in SQL Server. I need to find cumulative summation in SQL Server.
A variable will hold a integer value say 100. Let's say
Declare #Variable int = 100
Now the #NewVariable will have below formula:
#NewVariable = #Variable * (1 - 0.005)
Hence #NewVariable = 99.5
Now, the #NewestVariable will have below formula;
#NewestVariable = #NewVariable * (1 - 0.005)
Hence the #NewestVariable will have value of 99.00
Likewise this calculation will occur 24 times and all the results will be sum at the end.
Hence final result will be: 100 + 99.5 +99.00 + .... ...
I tried to achieve the desired result using #Count Variable (DECLARE #COUNT INT = 24) and using a While loop, but I'm not sure whether I'm correct or not?
Request your help!
Thanks!
You can do it using a CTE as below:
declare #variable int = 100
;with cte as
(
select convert(numeric(8,2), #variable) as var, 1 as recCount
union all
select convert(numeric(8,2), #variable * (1 - recCount*0.005)) as var, recCount+1 as recCount
from cte
where recCount < 24
)
select sum(var) as total from cte
Working Fiddle Demo
Edit: Adjusted to resolve rounding error as per #peter.petrov 's comment
If you need to get the values of each row before counting, please use this fiddle
Try this code.
declare #Variable decimal(20,10);
set #Variable = 100;
declare #Sum decimal(20,10);
set #Sum = 0;
declare #cnt int;
set #cnt = 1;
while (#cnt <= 24)
begin
set #Sum = #Sum + #Variable;
set #Variable = #Variable * (1.0 - 0.005);
set #cnt = #cnt + 1;
end;
select #Sum;
A simple answer would be like this
DECLARE #Variable INT = 100
SELECT #Variable
DECLARE #counter INT = 1
DECLARE #SumVariable NUMERIC(20,2) = #Variable
DECLARE #NewVariable NUMERIC(20,2) = #Variable
WHILE(#counter<24)
BEGIN
SET #NewVariable = #NewVariable * 0.995
SET #SumVariable = #SumVariable + #NewVariable
SET #counter = #counter+1
END
SELECT #SumVariable
You could also use a "quirky update" to avoid while-loops. If you're not interesed in intermediate resuls, just modify the last code line to select only the max(total).
DECLARE #total DECIMAL(10,3) = 0.000
;WITH "data" AS
(
SELECT CAST( 100 AS DECIMAL(10,3)) AS id
UNION ALL
SELECT CAST( id * ( 1 - 0.005 ) AS DECIMAL(10,3)) FROM "data" WHERE id > 100 * (1 - 21 * 0.005)
)
SELECT
id, total = CAST( 0.000 AS DECIMAL(10,3))
INTO #temp
FROM
"data"
OPTION ( MAXRECURSION 23 );
UPDATE t SET #total = total = #total + id FROM #temp t
SELECT * FROM #temp
See SQL-Fiddle for testing.
Please have a look at the code below and explain to me why there is a deviance in the final results. Note that the difference is the introduction of the brackets in the second calculation. Thanks!
Code:
DECLARE #A decimal(38,19) = 7958011.98
DECLARE #B decimal(38,19) = 10409029441
DECLARE #C decimal(38,19) = 10000000000
DECLARE #Z1 decimal(38,19)
DECLARE #Z2 decimal(38,19)
SET #Z1 = #A * #B / #C
SET #Z2 = #A * (#B / #C)
SELECT #Z1 AS [Correct],
#Z2 AS [Wrong]
Results:
Correct = 8283518.0991650000000000000
Wrong = 8283510.5860060000000000000
The intermediate datatypes are different because of this MSDN article
That is, (#B / #C) evaluated first, follows rules like this. The intermediate datatype then affects the multiplication by #A
You can see the intermediate and final types here (before assigning to a decimal(38,19) type
SELECT
#A * #B, -- decimal (x, 6)
#A * #B / #C, -- decimal (x, 6)
(#B / #C), -- decimal (x, 6)
#A * (#B / #C) -- decimal (x, 6)
So, instead of 1.0409029441 you get 1.040902 for your 2nd math
Note, your 1st is wrong too. It is actually 8283518.099165070318
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Truncate (not round) decimal places in SQL Server
Can't figure this out. I need 1 decimal place returned while SQL is rounding to whole numbers.
I read that integers divided by integers give integers in SQL, but I need the one truncated decimal place for value of output in the temp table.
I don't mind if 35.0 comes back as 35 but 35.17 should come back as 35.1. Sorry just edited. Need to truncate the last number, not round up.
create table #blah(output decimal(9,1))
DECLARE #a money
DECLARE #b money
DECLARE #intinterval decimal(9,1)
SET #a = 5
SET #b = 2
SET #intinterval = (#b / 1000.0) * (86400.0 / #a)
INSERT INTO #blah (output) VALUES (#intinterval)
SELECT * from #blah
drop table #blah
The above equation should give (2 / 1000) * (86400 / 5) = (0.002 * 17280) = 34.56
The 34.56 should truncate to 34.5
SET #intinterval = cast(10 * (#b / 1000.0) * (86400.0 / #a) as int) / 10.0
or
SET #intinterval = cast(#b * 864.0 / #a as int) / 10.0
What about Round((#b / 1000.0) * (86400.0 / #a), 1, 1), where last 1 saying to truncate instead of round.
try this with no special functions...
if
a = 5 then output = 34.5 (34.56)
a = 7 output = 24.6 (24.69)
a = 11 output = 15.7 (15.71)
create table #blah(output decimal(9,1))
DECLARE #a money
DECLARE #b money
DECLARE #intinterval decimal(9,2)
declare #rounded decimal(9,1)
declare #diff decimal(9,2)
declare #finalvalue decimal(9,1)
SET #a = 5
SET #b = 2
SET #intinterval = (#b / 1000.0) * (86400.0 / #a)
set #rounded = #intinterval -- gets the rounded value
set #diff = #intinterval - #rounded -- gets the difference whether to round off or not
if #diff >= 0 -- if differnce is >= 0 then get the rounded value .. eg. 34.31 = 34.3
set #finalvalue = #rounded
else -- else subtract 0.1 and get the rounded value e.g. 34.56 - 0.1 = 34.46 -> rounded value of 34.5
set #finalvalue = #intinterval - 0.1
INSERT INTO #blah (output) VALUES (#finalvalue )
SELECT * from #blah
drop table #blah