I have made mainly two changes to the old example - I defined the start, end and step to be numeric, while considering also an index into the output table. Here’s the modified function:
-- SQL Server 2005+: Numeric Interval CREATE FUNCTION dbo.fGetNInterval( @Start numeric(18,2) , @End numeric(18,2) , @Step numeric(18,2)) RETURNS @Interval TABLE( Ind int PRIMARY KEY , Val numeric(18,2)) AS BEGIN DECLARE @Sign smallint SET @Sign = IsNull(NullIf(Sign(@End-@Start), 0), 1); WITH CTE(Ind, Val) AS( SELECT Cast(1 as int) Ind , Cast(COALESCE(@Start, @End, 0) as numeric(18,2)) Val UNION ALL SELECT cast(Ind+1 as int) Ind , Cast(CTE.Val + @Step * @Sign as numeric(18,2)) Val FROM CTE WHERE (@End-CTE.Val)*@Sign-@Step>=0 ) INSERT @Interval SELECT Ind , Val FROM CTE OPTION(MAXRECURSION 0) RETURN END
--descending sequence SELECT UT.Val, 100/UT.Val FROM dbo.fGetNInterval(100, 25, 5) UT -- ascending sequence SELECT * FROM dbo.fGetNInterval(1, 2, 0.25)
-- matrix representation DECLARE @EE as numeric(18,2) = 100 SELECT UT.Val [UT %] , Max(CASE WHEN QF.Ind = 1 THEN Cast(QF.Val*@EE*100/UT.Val as numeric(18,1)) END) [80%] , Max(CASE WHEN QF.Ind = 2 THEN Cast(QF.Val*@EE*100/UT.Val as numeric(18,1)) END) [85%] , Max(CASE WHEN QF.Ind = 3 THEN Cast(QF.Val*@EE*100/UT.Val as numeric(18,1)) END) [90%] , Max(CASE WHEN QF.Ind = 4 THEN Cast(QF.Val*@EE*100/UT.Val as numeric(18,1)) END) [95%] , Max(CASE WHEN QF.Ind = 5 THEN Cast(QF.Val*@EE*100/UT.Val as numeric(18,1)) END) [100%] FROM dbo.fGetNInterval(100, 25, 5) UT , dbo.fGetNInterval(1, 2, 0.25) QF GROUP BY UT.Ind , UT.Val
Here’s the output:
Note:
The indexes were used to display the values into the needed format. The table-valued function could be created also without the respective indexes, however it would have complicated the query.
No comments:
Post a Comment