【问题标题】:Updating column based on previous value of other column in tsql根据sql中另一列的先前值更新列
【发布时间】:2017-06-06 00:26:55
【问题描述】:

我需要更新此查询中的目标列

CREATE TABLE #test 
(
     id INT IDENTITY(1,1),  
     score int, 
     goal int
)

INSERT INTO #test(score) VALUES (80)
INSERT INTO #test(score) VALUES (86)
INSERT INTO #test(score) VALUES (90)
INSERT INTO #test(score) VALUES (90)
INSERT INTO #test(score) VALUES (90)
INSERT INTO #test(score) VALUES (80)
INSERT INTO #test(score) VALUES (95)
INSERT INTO #test(score) VALUES (95)
INSERT INTO #test(score) VALUES (95)
INSERT INTO #test(score) VALUES (95)
INSERT INTO #test(score) VALUES (95)
INSERT INTO #test(score) VALUES (89)

--- initial goal 5
-- if score is 90 or above for 3 continuous week then goal is 3
-- if score is 95 or above for 5 continuous week then goal is 1

【问题讨论】:

标签: sql-server tsql


【解决方案1】:

几个快速笔记:

  1. 我修复了您的示例 sql 以添加日期。
  2. 我使用DATEADD 函数轻松计算周数。
  3. 根据您想要的逻辑,您可能需要调整更新中的DATEADD 函数。您不是 100% 清楚您是否想成为最终排他性的,所以我假设它们是最终包容性

你应该可以做类似这样的事情:

UPDATE  #Test
SET     Goal = 3
WHERE   Id IN ( SELECT  Id
                FROM    #Test AS t
                OUTER APPLY ( SELECT    COUNT(1) AS 'Number'
                              FROM      #Test AS t2
                              WHERE     t2.Date BETWEEN DATEADD(WEEK, -2, t.Date) AND t.Date AND
                                        t2.Score >= 90
                            ) AS t2
                WHERE   t2.Number >= 3 );

UPDATE  #Test
SET     Goal = 1
WHERE   Id IN ( SELECT  Id
                FROM    #Test AS t
                OUTER APPLY ( SELECT    COUNT(1) AS 'Number'
                              FROM      #Test AS t2
                              WHERE     t2.Date BETWEEN DATEADD(WEEK, -4, t.Date) AND t.Date AND
                                        t2.Score >= 95
                            ) AS t2
                WHERE   t2.Number >= 5 );

最难的部分是计算“滚动”数字。我正在使用OUTER APPLY 执行此操作,尽管它可以通过几种不同的方式完成。几年前我问过类似的question,解决方案是使用CROSS APPLY。因此,您的里程可能会有所不同,其他人可能有不同的解决方案,但这会让您对如何进行有一个很好的了解。

这是表格最终得到的结果集:


这是我用来生成表的 sql。如果您打算在最终结果中使用临时表,请不要忘记删除它们!

IF OBJECT_ID('tempdb..#Test') IS NOT NULL
    DROP TABLE #Test;

DECLARE @StartDate AS DATE = '2017-01-01';
CREATE TABLE #Test
    (
      Id INT IDENTITY(1, 1)
    , Score INT
    , Goal INT
    , Date DATE
    );
INSERT  INTO #Test
        ( Score, Date )
VALUES  ( 80, DATEADD(WEEK, 0, @StartDate) )  ,
        ( 86, DATEADD(WEEK, 1, @StartDate) )  ,
        ( 90, DATEADD(WEEK, 2, @StartDate) )  ,
        ( 90, DATEADD(WEEK, 3, @StartDate) )  ,
        ( 90, DATEADD(WEEK, 4, @StartDate) )  ,
        ( 80, DATEADD(WEEK, 5, @StartDate) )  ,
        ( 95, DATEADD(WEEK, 6, @StartDate) )  ,
        ( 95, DATEADD(WEEK, 7, @StartDate) )  ,
        ( 95, DATEADD(WEEK, 8, @StartDate) )  ,
        ( 95, DATEADD(WEEK, 9, @StartDate) )  ,
        ( 95, DATEADD(WEEK, 10, @StartDate) ) ,
        ( 89, DATEADD(WEEK, 11, @StartDate) );

DROP TABLE #Test;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多