t-sql nearest quarter hour - tsql

I'm looking for a way to return a value adjusted to the 'highest' quarter. I cannot round because the value returned cannot be greater than the original value. For example if the value is 53.290 I need to return 53.25 and 51.49 would return 51.25. Can I do this in t-sql?

The answer you've provided, Steve, of dividing by 0.25 has the same effect as this code. I'm not sure, but I feel that multiplication by four is clearer than divison by a fraction.
SELECT (FLOOR(#myValue * 4)) / 4.0

After working on this for a bit and doing some more research I think this is the best solution. Thanks everyone for the responses.
DECLARE #myvalue DECIMAL(8,4);
SET #myvalue = 53.26;
SELECT (Floor(#myvalue/.25)) * .25; -- Returns 53.25
SET #myvalue = 53.24;
SELECT (Floor(#myvalue/.25)) * .25; -- Returns 53.00

DECLARE #Value DECIMAL(10,4) = 53.290;
SELECT ROUND(#Value/25.00, 2) * 25
Result: 53.250000000
Rounded value to TWO Digits
SELECT CONVERT(DECIMAL(18, 2), ROUND(#Value/25.00, 2) * 25)
Result: 53.25

This will get the nearest quarter based on the values present on the right side of the decimal.I have just tried my hands on it. Hope it would be useful. Just try it with different values as well.
DECLARE #Value DECIMAL(10, 2) = 53.49
SELECT CASE
WHEN CAST(RIGHT(#Value, 2) AS FLOAT) > 0
AND CAST(RIGHT(#Value, 2) AS FLOAT) <= 49
THEN FLOOR(#Value) + 0.25
WHEN CAST(RIGHT(#Value, 2) AS FLOAT) > 49
AND CAST(RIGHT(#Value, 2) AS FLOAT) <= 74
THEN FLOOR(#Value) + 0.50
ELSE CEILING(#Value) - 0.25
END

Related

How do i format time into seconds in lua?

So basically I'm confused on how I'd make it so that I can convert DD:HH:MM:SS to only seconds while taking into account the amount of numbers there are. (Sorry if I make 0 sense, you should definitely know what I mean by the example below.)
print("05:00":FormatToSeconds()) -- 5 minutes and 0 seconds
-- 300
print("10:30:15":FormatToSeconds()) -- 10 hours, 30 minutes and 15 seconds
-- 37815
print("1:00:00:00":FormatToSeconds()) -- 1 day
-- 86400
print("10:00:00:30":FormatToSeconds()) -- 10 days, 30 seconds
-- 864030
So on and so forth. I think that maybe using gmatch would work but still idk. Help would be greatly appreciated.
Edit:
So I've tried doing it with gmatch, but I don't know if this is the most fastest way of doing this (which it probably isn't), so any help would still be appreciated.
(My code)
function ConvertTimeToSeconds(Time)
local Thingy = {}
local TimeInSeconds = 0
for v in string.gmatch(Time, "%d+") do
if tonumber(string.sub(v, 1, 1)) == 0 then
table.insert(Thingy, tonumber(string.sub(v, 2, 2)))
else
table.insert(Thingy, tonumber(v))
end
end
if #Thingy == 1 then
TimeInSeconds = TimeInSeconds + Thingy[1]
elseif #Thingy == 2 then
TimeInSeconds = TimeInSeconds + (Thingy[1] * 60) + Thingy[2]
elseif #Thingy == 3 then
TimeInSeconds = TimeInSeconds + (Thingy[1] * 60 * 60) + (Thingy[2] * 60) + Thingy[3]
elseif #Thingy == 4 then
TimeInSeconds = TimeInSeconds + (Thingy[1] * 24 * 60 * 60) + (Thingy[2] * 60 * 60) + (Thingy[3] * 60) + Thingy[4]
end
return TimeInSeconds
end
print(ConvertTimeToSeconds("1:00:00:00"))
Don't worry about execution speed before doing any actual measurements unless you're designing a time-critical program. In any extreme situation you'd probably want to offload risky parts to a C module.
Your approach is just fine. There are parts you can clean up: you can just return the results of calculations as TimeInSeconds doesn't actually act as accumulator in your case; tonumber handles '00' just fine and it can ensure decimal integers with an argument (since 5.3).
I'd go the other way and describe factors in a table:
local Factors = {1, 60, 60 * 60, 60 * 60 * 24}
local
function ConvertTimeToSeconds(Time)
local Components = {}
for v in string.gmatch(Time, "%d+") do
table.insert(Components, 1, tonumber(v, 10))
end
if #Components > #Factors then
error("unexpected time component")
end
local TimeInSeconds = 0
for i, v in ipairs(Components) do
TimeInSeconds = TimeInSeconds + v * Factors[i]
end
return TimeInSeconds
end
Of course, both implementations have problem with pattern being naïve as it would match e.g., '00 what 10 ever 10'. To fix that, you could go another route of using string.match with e.g., '(%d+):(%d+):(%d+):(%d+)' and enforcing strict format, or matching each possible variant.
Otherwise you can go all in and use LPeg to parse the duration.
Another way would be to not use strings internally, but instead convert them into a table like {secs=10, mins=1, hours=10, days=1} and then use these tables instead - getting seconds from that representation would be straight-forward.

How to calculate the percentage(%) in postgresql

I am not able to calculate the % in postgresql
Below the my code
v_total_repro_count = (select count(pm_task_run_bug_repro_id) from project.pm_task_run_bug_repro
where pm_task_run_bug_detail_id = 605)--5;
v_repro_count = (select count(pm_task_run_bug_repro_id) from project.pm_task_run_bug_repro
where execution_status = 'Reprod' and pm_task_run_bug_detail_id = 605)--3;
v_impact = select (5/3)*100; = answer = 100
v_impact = select (3/5)*100; = answer = 0
the answer getting 0 and 100 instead of 60%
Cast value to numeric
SELECT ROUND(( 3::NUMERIC/5::NUMERIC ) * 100);
If you want floating point results, you should use at least one float in your calculation, such that the entire expression is promoted to floating point:
select (3.0 / 5) * 100; -- returns 60

How to add number of days defined by float variable to a Date in SQL

I have a float variable which describes a term in months.
I need to be able to add this period to a given date.
I created a simple logic such as:
DECLARE #monthsTerm AS float = 2;
Select DATEADD(dd,((CAST(#monthsTerm AS INT) % 1) / 0.25 * 7), (DATEADD(mm, CAST(#monthsTerm AS INT), '2018-01-01'))) AS [Subscription end date]
The problem appears when I want to set the monthsTerm variable to a 1, 2 or 3 weeks, etc. period of time. So for two weeks period, the variable would look like:
DECLARE #monthsTerm AS float = 0.5;
and I expect to get '2018-01-15' as a result, but now it returns '2018-01-01' which is wrong.
I thought about transferring the expression to just a:
Select DATEADD(dd,((#monthsTerm % 1) / 0.25 * 7), (DATEADD(mm, CAST(#monthsTerm AS INT), '2018-01-01'))) AS [Subscription end date]
however, I'm getting an exception:
The data types float and int is incompatible in the modulo operator.
I know that for instance the similar expression would work in C#:
public DateTime EndDate
=> StartDate.AddMonths((int)TermMonths).AddDays((TermMonths % 1) / 0.25 * 7);
Is there any simple workaround to this so I can have only one simple expression with Select DATEADD(.. or I need to end up with some more complex solution? Cheers
Select
cast((CAST(#monthsTerm*100 as int) % 100)*7 /0.25/100 as int) as days ,
(((CAST(#monthsTerm*100 as int) % 100)/100) / 0.25 * 7),
DATEADD(dd,cast((CAST(#monthsTerm*100 as int) % 100)*7 /0.25/100 as int), (DATEADD(mm, CAST(#monthsTerm AS INT), '2018-01-01'))) AS [Subscription end date]
Multiplying with 100, and dividing by 100 after the %

PHP subtract a percentage result

$temp_price_1 = round($price * ((100-$sale_percentage) / 100), 2); $price = $temp_price_1;
im using this code to subtract a percentage from a number, for this example my starting number for $price is 24.99 and the $sale_percentage is 50.0 this result is the $temp_price_1 being 12.5 which is correct, however i need it to be 12.50 so it looks like a correct currency value. How do i add the 0 back on the end.
Many thanks
Check out the number_format function (returns a string):
number_format($price, 2);
Will return the string "12.50" when $price is set to 12.5

Round to the closest .25

Does anyone know of a way to round to the closest .25 in t-sql? Currently I am rounding down using
floor(value * 4)/4
My client is changing their algorithm and wants to do a midpoint round to the closest quarter. If the value is less than .125 round to 0.00, if the value is greater than or equal to .125 round up to .25.
use ROUND(value/25, 2) * 25 like this:
Example1:
DECLARE #value DECIMAL(18, 2)
SET #value = 1.126
SELECT CAST(ROUND(#value/25, 2) * 25 as numeric(18,2)) AS rounded_val
Output:
1.25
Example2:
DECLARE #value DECIMAL(18, 2)
SET #value = 1.124
SELECT CAST(ROUND(#value/25, 2) * 25 as numeric(18,2)) AS rounded_val
Output:
1.00
select Sample,
Round( ( Sample + Sign( Sample ) * 0.125 ) * 4, 0, 1 ) / 4.0 as Rounded
from ( values ( 0.0 ), ( 0.1 ), ( 1.125 ), ( 0.25 ), ( 10.5 ),
( -0.75 ), ( -0.875 ), ( -1.12 ), ( -1.125 ) )
as Samples( Sample )
Note that ROUND can be used to truncate the fractional part of a value regardless of the sign. FLOOR will always return a value equal to or less than the original value, which can be problematic when the value is negative.
I needed to round to an arbitrary precision & rounding strategy.
rounding to *.25
DECLARE #roundamt DECIMAL(16,2) = .25, #value DECIMAL(18, 2) = 1.7688
SELECT ROUND( (#value - FLOOR(#value)) / #roundamt, 0 ) * #roundamt + FLOOR(#value)
-- result = 1.750000
different rounding strategies like 0.02, 0.25, 0.5, 0.75
SELECT
x.roundamt, ROUND( (#value - FLOOR(#value)) / roundamt, 0 ) * roundamt + FLOOR(#value)
FROM
( VALUES (0.02), (0.25), (0.5), (0.75) )x(roundamt)
For anyone who need to find the closest divider without a remainder you can use:
SELECT (CAST(ROUND(#value / 0.25, 2) as int)) * 0.25
So basically this will round down to the closest multiple of 0.25