重新编号连续值

时间:2017-03-23 16:34:38

标签: sql-server

我有桌子,我有比赛日期和结果(0表示失败和1胜)

+------+--------------+--------+ 
| id   | game_date    | result | 
+------+--------------+--------+
| 1    | '2016-09-01' | 1      |
| 2    | '2016-09-02' | 1      |
| 3    | '2016-09-03' | 0      |
| 4    | '2016-09-04' | 1      |
| 5    | '2016-09-04' | 1      |
| 6    | '2016-09-04' | 1      |
| 7    | '2016-09-05' | 1      |
| 8    | '2016-09-06' | 0      |
| 9    | '2016-09-07' | 1      |

我需要获得所有胜利,胜利是连续的(按日期排序),并从1到最后一次胜利重新编号。

结果应为:

+------+--------------+--------+------------
| id   | game_date    | result | 
+------+--------------+--------+-------------
| 1    | '2016-09-01' | 1      | 1
| 2    | '2016-09-02' | 1      | 2
| 3    | '2016-09-03' | 0      |
| 4    | '2016-09-04' | 1      | 1
| 5    | '2016-09-04' | 1      | 2
| 6    | '2016-09-04' | 1      | 3
| 7    | '2016-09-05' | 1      | 4
| 8    | '2016-09-06' | 0      |
| 9    | '2016-09-07' | 1      | 1  

2 个答案:

答案 0 :(得分:3)

您可以通过识别相邻值组来完成此操作。一种简单的方法是行数的差异。另一种方法是为每个“0”值分配最大日期:

select id, game_date, result,
       (case when result = 1
             then row_number() over (partition by result, max_gamedate order by id)
        end) as newcol
from (select t.*,
             max(case when result = 0 then game_date end) over
                 (order by id) as max_gamedate
      from t
     ) t

答案 1 :(得分:0)

DECLARE @games TABLE (
    id INT,
    game_date DATE,
    result INT
);
INSERT INTO @games
VALUES
(1, '2016-09-01', 1),
(2, '2016-09-02', 1),
(3, '2016-09-03', 0),
(4, '2016-09-04', 1),
(5, '2016-09-04', 1),
(6, '2016-09-04', 1),
(7, '2016-09-05', 1),
(8, '2016-09-06', 0),
(9, '2016-09-07', 1);

WITH CTE AS(
    select t3.*,   COUNT(collect) OVER(PARTITION BY collect) as collect_count FROM (
        select t.*, t2.rn, sum(result) over(order by game_date, t.id) as collect from @games t 
        left join (
            SELECT id, row_number() over(order by game_date, id) as rn
            FROM @games t where result  = 1
        )  t2
        on t.id = t2.id
    )t3
)
select CTE.id, CTE.game_date, CTE.result, rn - COALESCE( (SELECT MAX(collect) FROM CTE innert WHERE collect < CTE.rn and collect_count > 1) , 0) sequence_number 
FROM CTE
order by game_date, id