我有一张这样的表:
id_nbr t1 t2 t3 t4 t5 t6
1111 10 20 30 40 50 40
2222 40 10 50 20 70 90
我想建立一个函数,每个id_nbr将返回最大减法和该减法的时间差异 - 例如:
对于id_nbr 1111,从t1到t5的最大值为40,因此该函数将在不同的单元格中返回40和4(5-1)。 对于id_nbr 2222,从t2到t5的最大值为60,因此函数将在diffrennt单元格中返回60和3(5-2)。
Output:
exec find_max_and_time (1111)
max_diff time
40 4
创建此类功能的任何帮助?
查询中建议的功能:
答案 0 :(得分:0)
这里有一个可能的解决方案,通过unpivot。我们的想法是将您的六列变为行,将其rowindex表示为时间(根据您的示例),然后获取相应列的最小值和最大值。但是,您应该考虑处理重复项:可能会发生两个列具有相同的值,并且使用此列可以为最小值和最大值创建多个匹配记录。
DECLARE @t TABLE(
id_nbr INT
,t1 INT
,t2 INT
,t3 INT
,t4 INT
,t5 INT
,t6 INT
);
INSERT INTO @t VALUES (1111,10,20,30,40,50,40), (2222,40,10,50,20,70,90);
DECLARE @SearchID INT = 2222;
DECLARE @TimeIdxFrom INT = 1;
DECLARE @TimeIdxTo INT = 5;
WITH cteBase AS(
SELECT id_nbr, ROW_NUMBER() OVER (PARTITION BY id_nbr ORDER BY (SELECT 1)) rn, times
FROM (
SELECT id_nbr, t1, t2, t3, t4, t5, t6
FROM @t t) t
UNPIVOT(
times FOR cTime IN (t1, t2, t3, t4, t5, t6)
) u
),
cteMinMax AS(
SELECT id_nbr, MIN(times) MinTime, MAX(times) MaxTime
FROM cteBase
WHERE rn >= @TimeIdxFrom
AND rn <= @TimeIdxTo
GROUP BY id_nbr
)
SELECT --*,
cbMax.rn - cbMin.rn AS TimeSpan,
cbMax.times - cbMin.times AS ValDiff
FROM cteMinMax AS cmm
JOIN cteBase AS cbMin ON cmm.id_nbr = cbMin.id_nbr AND cbMin.times = cmm.MinTime
JOIN cteBase AS cbMax ON cmm.id_nbr = cbMax.id_nbr AND cbMax.times = cmm.MaxTime
WHERE cbMax.id_nbr = @SearchID;
答案 1 :(得分:0)
NULL返回所有计算值
CREATE TABLE dbo.T
(
id_nbr INT,
t1 INT,
t2 INT,
t3 INT,
t4 INT,
t5 INT,
t6 INT
)
GO
INSERT INTO dbo.T (id_nbr, t1, t2, t3, t4, t5, t6)
VALUES
( 1111, 10, 20, 30, 40, 50, 40 ),
(2222, 40, 10, 50, 20, 70, 90 )
GO
CREATE FUNCTION dbo.find_max_and_time(@Id INT)
RETURNS TABLE
AS RETURN
WITH Desce AS
(
SELECT TOP 1 WITH TIES a.id_nbr , b.*
FROM dbo.T a
CROSS APPLY
(
SELECT 1, a.T1 UNION ALL
SELECT 2, a.T2 UNION ALL
SELECT 3, a.T3 UNION ALL
SELECT 4, a.T4 UNION ALL
SELECT 5, a.T5 UNION ALL
SELECT 6, a.T6
) as b(N,Val)
WHERE id_nbr = @Id OR @Id IS NULL
ORDER BY ROW_NUMBER() OVER(PARTITION BY id_nbr ORDER BY Val DESC)
), Asce AS
(
SELECT TOP 1 WITH TIES a.id_nbr,b.*
FROM dbo.T a
CROSS APPLY
(
SELECT 1, a.T1 UNION ALL
SELECT 2, a.T2 UNION ALL
SELECT 3, a.T3 UNION ALL
SELECT 4, a.T4 UNION ALL
SELECT 5, a.T5 UNION ALL
SELECT 6, a.T6
) as b(N,Val)
WHERE id_nbr = @Id OR @Id IS NULL
ORDER BY ROW_NUMBER() OVER(PARTITION BY id_nbr ORDER BY Val ASC)
)
SELECT
a.id_nbr,
a.Val - b.Val as Val,
a.N - b.N as N
FROM
Desce a
INNER JOIN
Asce b
ON a.id_nbr = b.id_nbr
GO
SELECT * FROM dbo.find_max_and_time (1111)
DROP TABLE dbo.T
DROP FUNCTION dbo.find_max_and_time