首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在sql中创建减法矩阵

在sql中创建减法矩阵
EN

Stack Overflow用户
提问于 2017-10-23 16:05:52
回答 2查看 43关注 0票数 0

我有一张这样的桌子:

代码语言:javascript
复制
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,因此函数将返回60和3 (5-2)的差异单元格。

代码语言:javascript
复制
Output:
exec find_max_and_time (1111) 

max_diff time
  40      4

创建这样的函数有什么帮助吗?

查询中建议的函数如下:

EN

回答 2

Stack Overflow用户

发布于 2017-10-23 16:43:03

这里有一种可能的解决方案是通过unpivot。其思想是将六列转换为行,获得表示时间的rowindex (根据您的示例),然后获得相应列的最小和最大值。但是,您应该考虑处理重复项:可能会发生这种情况,即两个列具有相同的值,这样您就可以拥有多个匹配的min和max记录。

代码语言:javascript
复制
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;
票数 0
EN

Stack Overflow用户

发布于 2017-10-23 16:55:41

NULL返回所有计算值

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46884557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档