基于行值SQL Server导出和更新列值

时间:2017-04-21 11:06:04

标签: sql sql-server

所以我有一个Request History表,我想标记它的版本(版本基于循环结束);我能够标记循环的结束,但不知怎的,我无法更新每个循环的每个循环的值。这是一个例子:

    |history_id   | Req_id | StatID | Time      |EndCycleDate |
    |-------------|---------|-------|---------- |-------------|
    |1            | 1       |18     | 3/26/2017 |   NULL      |
    |2            | 1       | 19    | 3/26/2017 |   NULL      |
    |3            | 1       |20     | 3/30/2017 |   NULL      |
    |4            |1        | 23    |3/30/2017  |   NULL      |
    |5            | 1       |35     |3/30/2017  |   3/30/2017 |
    |6            | 1       |33     |4/4/2017   |   NULL      |
    |7            | 1       |34     |4/4/2017   |   NULL      |
    |8            | 1       |39     |4/4/2017   |   NULL      |
    |9            | 1       |35     |4/4/2017   |   4/4/2017  |
    |10           | 1       |33     |4/5/2017   |   NULL      |
    |11           | 1       |34     |4/6/2017   |   NULL      |
     |12          | 1       |39     |4/6/2017   |   NULL      |
    |13           | 1       |35     |4/7/2017   |   4/7/2017  |
    |14           | 1       |33     |4/8/2017   |   NULL      |
    |15           | 1       |  34   |4/8/2017   |   NULL      |
    |16           | 2       |18     |3/28/2017  |   NULL      |
    |17           | 2       |26     |3/28/2017  |   NULL      |
    |18           | 2       |20     |3/30/2017  |   NULL      |
    |19           | 2       |23     |3/30/2017  |   NULL      |
    |20           | 2       |35     |3/30/2017  |   3/30/2017 |
    |21           | 2       |33     |4/12/2017  |   NULL      |
    |22           | 2       |34     |4/12/2017  |   NULL      |
    |23           | 2       |38     |4/13/2017  |   NULL      |

现在我想要实现的是派生一个新列,即VER,并更新其值,如下所示:

    |history_id   | Req_id | StatID | Time      |EndCycleDate | VER  |
    |-------------|---------|-------|---------- |-------------|------|
    |1            | 1       |18     | 3/26/2017 |   NULL      |  1   |
    |2            | 1       | 19    | 3/26/2017 |   NULL      |  1   |
    |3            | 1       |20     | 3/30/2017 |   NULL      |  1   |
    |4            |1        | 23    |3/30/2017  |   NULL      |  1   |
    |5            | 1       |35     |3/30/2017  |   3/30/2017 |  1   |
    |6            | 1       |33     |4/4/2017   |   NULL      |  2   |
    |7            | 1       |34     |4/4/2017   |   NULL      |  2   |
    |8            | 1       |39     |4/4/2017   |   NULL      |  2   |
    |9            | 1       |35     |4/4/2017   |   4/4/2017  |  2   |
    |10           | 1       |33     |4/5/2017   |   NULL      |  3   |
    |11           | 1       |34     |4/6/2017   |   NULL      |  3   |
    |12           | 1       |39     |4/6/2017   |   NULL      |  3   |
    |13           | 1       |35     |4/7/2017   |   4/7/2017  |  3   |
    |14           | 1       |33     |4/8/2017   |   NULL      |  4   |
    |15           | 1       |  34   |4/8/2017   |   NULL      |  4   |
    |16           | 2       |18     |3/28/2017  |   NULL      |  1   |
    |17           | 2       |26     |3/28/2017  |   NULL      |  1   |
    |18           | 2       |20     |3/30/2017  |   NULL      |  1   |
    |19           | 2       |23     |3/30/2017  |   NULL      |  1   |
    |20           | 2       |35     |3/30/2017  |   3/30/2017 |  1   |
    |21           | 2       |33     |4/12/2017  |   NULL      |  2   |
    |22           | 2       |34     |4/12/2017  |   NULL      | 2    |
    |23           | 2       |38     |4/13/2017  |   NULL      | 2    |

1 个答案:

答案 0 :(得分:3)

真正接近的一种方法是累积计数:

select t.*,
       count(endCycleDate) over (partition by req_id order by history_id) as ver
from t;

但是,当endCycle日期定义完全正确时,这不会得到值。值从0开始。这些问题中的大多数都是通过窗口句来修复的:

select t.*,
       (count(endCycleDate) over (partition by req_id 
                                  order by history_id
                                  rows between unbounded preceding and 1 preceding) + 1
       ) as ver
from t;

但是错过了第一行第一行的价值。所以,这是一个实际工作的方法。它枚举值向后,然后从总计中减去以升序获取版本:

select t.*,
       (1 + count(*) over (partition by req_id) -
        (count(endCycleDate) over (partition by req_id 
                                   order by history_id desc)
       ) as ver
from t;