<< Click to Display Table of Contents >> Navigation: Live > Agents > Transformation Agents > Data Deriver > Examples > Live Data Deriver Agent – customFunction |
In cases where the SQL for calculating derived values becomes too long, or too complex, to maintain in the SERIES_FUNCTION_INFO, a custom scalar function can be used to encapsulate the computation logic. The custom function must return a single value, a REAL (NULL is allowed), and take the input parameters in the following example. Set the SERIES_FUNCTION_INFO JSON value to the name of your function (e.g., equis.median) and customFunction to true (e.g., { "sourceSeriesId": [1234], "frequency": "1hh", "value": "equis.median", "customFunction": true }).
-- Returns the specified target series' MEDIAN DT_LOGGER_DATUM.DATUM_VALUE, -- for the specified date and time interval.
-- https://docs.microsoft.com/en-us/sql/t-sql/functions/aggregate-functions-transact-sql -- Aggregate Functions (Transact-SQL) -- There is no MEDIAN Aggregate Function in SQL Server.
-- Future Enhancements: -- Use a more efficient / complex MEDIAN implementation? -- https://stackoverflow.com/questions/1342898/function-to-calculate-median-in-sql-server
IF OBJECT_ID(N'[equis].[median]') IS NOT NULL DROP FUNCTION [equis].[median]; GO
CREATE FUNCTION [equis].[median] ( @target_series_id INT -- the ID of the target / derived series for which the calculation is being performed ,@dateFrom DATETIME -- interval's start date ,@dateTo DATETIME -- interval's end date ,@includeFrom_YN CHAR -- 'Y' if interval's start date is inclusive, else 'N' ,@includeTo_YN CHAR -- 'Y' if interval's end date is inclusive, else 'N' ) RETURNS REAL -- calculated value for the interval AS BEGIN DECLARE @source_series_ids TABLE (id int); INSERT INTO @source_series_ids (id) SELECT * FROM equis.get_source_series_ids(@target_series_id);
DECLARE @median REAL;
SELECT @median = ( (SELECT MAX(datum_value) FROM (SELECT TOP 50 PERCENT datum_value FROM dt_logger_datum -- For now, assume @includeFrom_YN and @includeTo_YN = 'Y' (Yes). WHERE logger_series_id IN (SELECT id FROM @source_series_ids) AND datum_utc_dt >= @dateFrom AND datum_utc_dt <= @dateTo ORDER BY datum_value) AS bottomHalf) + (SELECT MIN(datum_value) FROM (SELECT TOP 50 PERCENT datum_value FROM dt_logger_datum WHERE logger_series_id IN (SELECT id FROM @source_series_ids) AND datum_utc_dt >= @dateFrom AND datum_utc_dt <= @dateTo ORDER BY datum_value DESC) AS topHalf) ) / 2;
RETURN @median; END
|
---|
-- Returns the specified target series' sourceSeriesId(s).
-- Future Enhancements: -- Use JSON Data functions, available starting with SQL Server 2016? -- https://docs.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server
IF OBJECT_ID(N'[equis].[get_source_series_ids]') IS NOT NULL DROP FUNCTION [equis].[get_source_series_ids]; GO
CREATE FUNCTION [equis].[get_source_series_ids] ( @target_series_id INT -- the ID of the target / derived series for which this calculation is being performed ) RETURNS @source_series_ids TABLE (id int) AS BEGIN -- @source_series_ids = { 1234, 5678 } INSERT INTO @source_series_ids (id) SELECT DISTINCT TRY_CAST(id.value AS BIGINT) FROM dt_logger_series s -- 1) Get SUBSTRING between '[' and ']', e.g. '[1234,5678]'; -- assumes there is only one '[' and one ']' and it's the sourceSeriesId array; -- future enhancement: use SQL Server 2016+ JSON Functions? -- 2) REPLACE '[', ',', and ']' with '|', and ' ', '\r', and '\n' with ''. -- 3) SPLIT pipe separated values into a table. CROSS APPLY equis.split(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(SUBSTRING(s.series_function_info, CHARINDEX('[', s.series_function_info), CHARINDEX(']', s.series_function_info) - CHARINDEX('[', s.series_function_info) + Len(']')), '[', '|'), ',', '|'), ']', '|'), ' ', ''), CHAR(13), ''), CHAR(10), '')) AS id WHERE (s.logger_series_id = @target_series_id) -- s.series_function_info = '{"sourceSeriesId":[1234,5678],"frequency":"1hh","value":"equis.median","customFunction":true}' AND (s.series_function_info LIKE LOWER('%sourceseriesid%:%[[]%]%')) -- '[[]' = '['
RETURN END
|
---|
Copyright © 2024 EarthSoft, Inc. • Modified: 26 Apr 2022