95 flow rate calculation value SQL function

I use the Solarwinds system, part of the contents on the combination of Solarwinds system write together. Finally, the floor is automatically reports the timing system and may Report mail.
However, the calculation method is defined by the SQL function, and then use the SQL query to get to, and this part is universal.

95th calculation method

"95th" keyword Solarwinds can be obtained from the official website to search the documentation.
Percentile Calculations in Orion at The 95th Platform:
https://documentation.solarwinds.com/en/Success_Center/orionplatform/Content/Core-95th-Percentile-Calculations-sw80.htm

  1. Over the 10 hours, the following 120 values were collected for inbound traffic (Mb/s):

    0.149 0.623 0.281 0.136 0.024 0.042 0.097 0.185 0.198 0.243 0.274 0.390 0.971 0.633 0.238 0.142 
    0.119 0.176 0.131 0.127 0.169 0.223 0.291 0.236 0.124 0.072 0.197 0.105 0.138 0.233 0.374 0.290 
    0.871 0.433 0.248 0.242 0.169 0.116 0.121 0.427 0.249 0.223 0.231 0.336 0.014 0.442 0.197 0.125 
    0.108 0.244 0.264 0.190 0.471 0.033 0.228 0.942 0.219 0.076 0.331 0.227 0.849 0.323 0.221 0.196 
    0.223 0.642 0.197 0.385 0.098 0.263 0.174 0.690 0.571 0.233 0.208 0.242 0.139 0.186 0.331 0.124 
    0.249 0.643 0.481 0.936 0.124 0.742 0.497 0.085 0.398 0.643 0.074 0.590 0.771 0.833 0.438 0.242 
    0.092 0.376 0.231 0.627 0.249 0.663 0.181 0.636 0.224 0.342 0.697 0.285 0.108 0.211 0.074 0.490 
    0.271 0.133 0.338 0.242 0.519 0.376 0.331 0.227 
  2. The values are reordered from high to low.

    0.971 0.942 0.936 0.871 0.849 0.833 0.771 0.742 0.697 0.690 0.663 0.643 0.643 0.642 0.636 0.633 
    0.627 0.623 0.590 0.571 0.519 0.497 0.490 0.481 0.471 0.442 0.438 0.433 0.427 0.398 0.390 0.385 
    0.376 0.376 0.374 0.342 0.338 0.336 0.331 0.331 0.331 0.323 0.291 0.290 0.285 0.281 0.274 0.271 
    0.264 0.263 0.249 0.249 0.249 0.248 0.244 0.243 0.242 0.242 0.242 0.242 0.238 0.236 0.233 0.233 
    0.231 0.231 0.228 0.227 0.227 0.224 0.223 0.223 0.223 0.221 0.219 0.211 0.208 0.198 0.197 0.197 
    0.197 0.196 0.190 0.186 0.185 0.181 0.176 0.174 0.169 0.169 0.149 0.142 0.139 0.138 0.136 0.133 
    0.131 0.127 0.125 0.124 0.124 0.124 0.121 0.119 0.116 0.108 0.108 0.105 0.098 0.097 0.092 0.085 
    0.076 0.074 0.074 0.072 0.042 0.033 0.024 0.014 
  3. The first 6 values are dropped, as these equal the top 5% of the values.

    0.771 0.742 0.697 0.690 0.663 0.643 0.643 0.642 0.636 0.633 0.627 0.623 0.590 0.571 0.519 0.497 
    0.490 0.481 0.471 0.442 0.438 0.433 0.427 0.398 0.390 0.385 0.376 0.376 0.374 0.342 0.338 0.336 
    0.331 0.331 0.331 0.323 0.291 0.290 0.285 0.281 0.274 0.271 0.264 0.263 0.249 0.249 0.249 0.248 
    0.244 0.243 0.242 0.242 0.242 0.242 0.238 0.236 0.233 0.233 0.231 0.231 0.228 0.227 0.227 0.224 
    0.223 0.223 0.223 0.221 0.219 0.211 0.208 0.198 0.197 0.197 0.197 0.196 0.190 0.186 0.185 0.181 
    0.176 0.174 0.169 0.169 0.149 0.142 0.139 0.138 0.136 0.133 0.131 0.127 0.125 0.124 0.124 0.124 
    0.121 0.119 0.116 0.108 0.108 0.105 0.098 0.097 0.092 0.085 0.076 0.074 0.074 0.072 0.042 0.033 
    0.024 0.014 
  4. The 95th percentile is 0.771.

SQL function

Tools are installed on the system: SQL Server Management Studio

New Function command template

New inline table valued function:

-- ================================================
-- Template generated from Template Explorer using:
-- Create Inline Function (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the function.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE FUNCTION <Inline_Function_Name, sysname, FunctionName> 
(   
    -- Add the parameters for the function here
    <@param1, sysname, @p1> <Data_Type_For_Param1, , int>, 
    <@param2, sysname, @p2> <Data_Type_For_Param2, , char>
)
RETURNS TABLE 
AS
RETURN 
(
    -- Add the SELECT statement with parameter references here
    SELECT 0
)
GO

New multi-statement table-valued function:

-- ================================================
-- Template generated from Template Explorer using:
-- Create Multi-Statement Function (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the function.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE FUNCTION <Table_Function_Name, sysname, FunctionName> 
(
    -- Add the parameters for the function here
    <@param1, sysname, @p1> <data_type_for_param1, , int>, 
    <@param2, sysname, @p2> <data_type_for_param2, , char>
)
RETURNS 
<@Table_Variable_Name, sysname, @Table_Var> TABLE 
(
    -- Add the column definitions for the TABLE variable here
    <Column_1, sysname, c1> <Data_Type_For_Column1, , int>, 
    <Column_2, sysname, c2> <Data_Type_For_Column2, , int>
)
AS
BEGIN
    -- Fill the table variable with the rows for your result set

    RETURN 
END
GO

New scalar-valued function:

-- ================================================
-- Template generated from Template Explorer using:
-- Create Scalar Function (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the function.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
CREATE FUNCTION <Scalar_Function_Name, sysname, FunctionName> 
(
    -- Add the parameters for the function here
    <@Param1, sysname, @p1> <Data_Type_For_Param1, , int>
)
RETURNS <Function_Data_Type, ,int>
AS
BEGIN
    -- Declare the return variable here
    DECLARE <@ResultVar, sysname, @Result> <Function_Data_Type, ,int>

    -- Add the T-SQL statements to compute the return value here
    SELECT <@ResultVar, sysname, @Result> = <@Param1, sysname, @p1>

    -- Return the result of the function
    RETURN <@ResultVar, sysname, @Result>

END
GO

Computing function system Solarwinds 95th of

By scalar-valued function to achieve.
A total of three, In a direction GetInBps95th, a direction Out GetOutBps95th.
In and Out as well as the direction of a single time point to take a large value calculation result.
Function already in the system, here is a function of command to modify the template.

In calculating the direction 95th

USE [SolarwindsOrion]
GO
/****** Object:  UserDefinedFunction [dbo].[GetInBps95th]    Script Date: 2019/11/14 11:07:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[GetInBps95th] 
(
    @InterfaceId int,
    @StartDate DateTime,
    @EndDate DateTime
)
RETURNS real
AS
BEGIN
    DECLARE @ResultVar real

    SELECT @ResultVar = MAX(In_Maxbps)
    FROM (
        SELECT TOP 95 PERCENT In_Maxbps
        FROM dbo.InterfaceTraffic WITH (NOLOCK)
        WHERE InterfaceID = @InterfaceId AND DateTime >= @StartDate AND DateTime <= @EndDate
        ORDER BY In_Maxbps ASC
    ) AS AA

    RETURN @ResultVar

END

Out of just changing the direction of a field, the other are the same.

Calculated bi-95th

USE [SolarwindsOrion]
GO
/****** Object:  UserDefinedFunction [dbo].[GetMaxBps95th]    Script Date: 2019/11/14 11:08:42 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[GetMaxBps95th] 
(
    @InterfaceId int,
    @StartDate DateTime,
    @EndDate DateTime
)
RETURNS real
AS
BEGIN
    DECLARE @ResultVar real

    SELECT @ResultVar = MAX(Maxbps)
    FROM (
        SELECT TOP 95 PERCENT Maxbps
        FROM (SELECT (CASE WHEN Out_Maxbps > In_Maxbps THEN Out_Maxbps ELSE In_Maxbps END) AS Maxbps
            FROM dbo.InterfaceTraffic WITH (NOLOCK)
            WHERE InterfaceID = @InterfaceId AND DateTime >= @StartDate AND DateTime <= @EndDate) AS MaxbpsSet
        ORDER BY Maxbps ASC
    ) AS AA

    RETURN @ResultVar

END

Multi-layer subqueries, WHEN clause used for determination assumes a large value.

Custom Functions

Because the original function can not meet the demand, the need to change it, to increase a variable period of time screening. Demand is a week or a month, just take the data working hours per day.
Herein by the number of hours 'DATEPART (hh, DateTime)' is 9 to 16 as long as these values represent on a day of 9:00 to 17:00.
There is also a demand time period is 2 day time period, taking into account the versatility, the manner used here to set the array, the values that define the desired array hours. Not actually an array, to simulate the string.

Creating custom functions

Create a custom function, based on the original function, increase the screening period:

USE [SolarwindsOrion]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Steed Xu
-- Create date: 2019/11/14
-- Description: Base on GetInBps95th, add BusyHours.
-- =============================================
CREATE FUNCTION [dbo].[GetInBps95thBusyHours] 
(
    @InterfaceId int,
    @StartDate DateTime,
    @EndDate DateTime,
    @BusyHours VarChar(64)
)
RETURNS real
AS
BEGIN
    DECLARE @ResultVar real

    SELECT @ResultVar = MAX(In_Maxbps)
    FROM (
        SELECT TOP 95 PERCENT In_Maxbps
        FROM dbo.InterfaceTraffic WITH (NOLOCK)
        WHERE InterfaceID = @InterfaceId 
            AND DateTime >= @StartDate AND DateTime <= @EndDate
            AND ','+RTRIM(@BusyHours)+',' LIKE '%,'+CAST(DATEPART(hh,DateTime) AS varchar)+',%'
        ORDER BY In_Maxbps ASC
    ) AS AA

    RETURN @ResultVar

END
GO

After executing the above statement will be added to the database.
Note: this time to define a string variable specified size, although otherwise be performed successfully, but the results will be expected and is not the same.

An array of problem-solving

Take time using the number of hours screening mode, which a few hours a day is needed, it is defined in the array.
When used in this definition:

DECLARE @BusyHours VarChar(64)
SET @BusyHours = '9,10,11,12,13,14,15,16'

Such data is to take 9:00 to 17:00.

Corresponding WHERE can write:

WHERE ','+RTrim(@BusyHours)+',' LIKE '%,'+CAST(datepart(hh,DateTime) AS VarChar)+',%'

Substantially simulate the effect of a string array, here it is enough.

Modify the custom function

If you create the wrong time, it can be modified using the following template and update the database.

USE [SolarwindsOrion]
GO
/****** Object:  UserDefinedFunction [dbo].[GetInBps95thBusyHours]    Script Date: 2019/11/14 13:43:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Steed Xu
-- Create date: 2019/11/14
-- Description: Base on GetInBps95th, add BusyHours.
-- =============================================
ALTER FUNCTION [dbo].[GetInBps95thBusyHours]
(
    @InterfaceId int,
    @StartDate DateTime,
    @EndDate DateTime,
    @BusyHours VarChar(64)
)
RETURNS real
AS
BEGIN
    DECLARE @ResultVar real

    SELECT @ResultVar = MAX(In_Maxbps)
    FROM (
        SELECT TOP 95 PERCENT In_Maxbps
        FROM dbo.InterfaceTraffic WITH (NOLOCK)
        WHERE InterfaceID = @InterfaceId 
            AND DateTime >= @StartDate AND DateTime <= @EndDate 
            AND ','+RTRIM(@BusyHours)+',' LIKE '%,'+CAST(DATEPART(hh,DateTime) AS varchar)+',%'
        ORDER BY In_Maxbps ASC
    ) AS AA

    RETURN @ResultVar

END

Call functions in SQL

Suppliers to use the template

Complete SQL query:

完整的查询语句如下:
SET NOCOUNT OFF
SET ROWCOUNT 0

DECLARE @StartDate DateTime
DECLARE @EndDate DateTime

SET @StartDate = CAST((ROUND(CAST(GetDate() - 7 AS FLOAT), 0, 1)) as datetime)
SET @EndDate = GetDate()

SELECT Interfaces.InterfaceId,
    Nodes.NodeID,
    Nodes.Caption AS NodeName,
    Nodes.VendorIcon AS Vendor_Icon,
    Interfaces.Caption AS Interface_Caption,
    Interfaces.InterfaceIcon AS Interface_Icon,
    Maxbps_In95,
    Maxbps_Out95,
    Maxbps_95
FROM Nodes
INNER JOIN Interfaces ON Nodes.NodeID = Interfaces.NodeID
INNER JOIN (
    SELECT InterfaceID,
        dbo.GetInBps95th(InterfaceID, @StartDate, @EndDate) AS Maxbps_In95,
        dbo.GetOutBps95th(InterfaceID, @StartDate, @EndDate) AS Maxbps_Out95,
        dbo.GetMaxBps95th(InterfaceID, @StartDate, @EndDate) AS Maxbps_95
    FROM InterfaceTraffic
    WHERE InterfaceTraffic.DateTime >= @StartDate AND InterfaceTraffic.DateTime <= @EndDate
    GROUP BY InterfaceID
) TrafficStat
ON Interfaces.InterfaceID = TrafficStat.InterfaceID
WHERE (1=1)
AND  
(
    (Nodes.Vendor = 'Cisco') AND
    (Interfaces.Comments = 'MT')
)
ORDER BY 
Maxbps_In95 desc,
Maxbps_Out95 desc

Modify the query on demand

Demand is to calculate the data of the week, here is the data acquisition last week, from Monday start.
Complete the query:

SET NOCOUNT OFF
SET ROWCOUNT 0

DECLARE @StartDate DateTime
DECLARE @EndDate DateTime
DECLARE @BusyHours VarChar(64)

SET @StartDate = DATEADD(week,-1,DATEADD(week,DATEDIFF(week,0,getdate()),0))
SET @EndDate = DATEADD(week,DATEDIFF(week,0,getdate()),0)
SET @BusyHours = '9,10,11,12,13,14,15,16'

SELECT Interfaces.InterfaceId,
    Nodes.NodeID,
    Nodes.Caption AS NodeName,
    Nodes.VendorIcon AS Vendor_Icon,
    Nodes.IP_Address,
    Interfaces.InterfaceName AS Interface_Name,
    Interfaces.InterfaceAlias AS Description,
    Interfaces.InterfaceIcon AS Interface_Icon,
    Maxbps_In95,
    Maxbps_Out95,
    @StartDate AS StartDate,
    @EndDate AS EndDate,
    @BusyHours AS BusyHours,
    Interfaces.Status AS Interfaces_Status
FROM Nodes
INNER JOIN Interfaces ON Nodes.NodeID = Interfaces.NodeID
INNER JOIN (
    SELECT InterfaceID,
        dbo.GetInBps95thBusyHours(InterfaceID, @StartDate, @EndDate, @BusyHours) AS Maxbps_In95,
        dbo.GetOutBps95thBusyHours(InterfaceID, @StartDate, @EndDate, @BusyHours) AS Maxbps_Out95
    FROM InterfaceTraffic
    WHERE InterfaceTraffic.DateTime >= @StartDate
        AND InterfaceTraffic.DateTime <= @EndDate
        AND ','+RTRIM(@BusyHours)+',' LIKE '%,'+CAST(DATEPART(hh,DateTime) AS varchar)+',%'
    GROUP BY InterfaceID
) TrafficStat
ON Interfaces.InterfaceId = TrafficStat.InterfaceId
WHERE (1=1)
    AND Nodes.IP_Address IN ('172.16.6.1','172.16.6.2','172.16.5.3','172.16.10.1','172.16.10.2','172.16.5.4')
    AND Interfaces.InterfaceAlias <> ''
    AND Interfaces.Status IN (1,2)
ORDER BY Interfaces.InterfaceId

Note: this time to define a string variable specified size, although otherwise be performed successfully, but the results will be expected and is not the same.

Verification results

In writing a query, all the data traffic at a port to export. Verify whether the result of the function in line with expectations.
Complete the query:

SET NOCOUNT OFF
SET ROWCOUNT 0

DECLARE @StartDate DateTime
DECLARE @EndDate DateTime
DECLARE @BusyHours VarChar(64)
DECLARE @InterfaceId int

SET @StartDate = DATEADD(week,-1,DATEADD(week,DATEDIFF(week,0,getdate()),0))
SET @EndDate = DATEADD(week,DATEDIFF(week,0,getdate()),0)
SET @BusyHours = '9,10,11,12,13,14,15,16'
SET @InterfaceId = 28993

SELECT TOP 95 PERCENT 
    DateTime, InterfaceID, In_Maxbps, Out_Maxbps, 
    @StartDate AS StartDate,
    @EndDate AS EndDate,
    @BusyHours AS BusyHours
FROM InterfaceTraffic
WHERE InterfaceTraffic.DateTime >= @StartDate
    AND InterfaceTraffic.DateTime <= @EndDate
    AND ','+RTrim(@BusyHours)+',' LIKE '%,'+CAST(datepart(hh,DateTime) AS VarChar)+',%'
    AND InterfaceID = @InterfaceId
ORDER BY In_Maxbps ASC

Guess you like

Origin blog.51cto.com/steed/2450351
Recommended