根据另一列

时间:2017-03-23 09:18:43

标签: sql sql-server tsql

我想增加一列,然后根据另一列中的值停止并重新开始。

例如:

我有一张桌子:

CustomerID  Reportdate  True_False
9001        2013-01-01  0
9001        2013-02-01  0
9001        2013-03-01  0
9001        2013-04-01  1
9001        2013-05-01  0
9001        2013-06-01  1
9001        2013-07-01  1
9001        2013-08-01  0
9001        2013-09-01  1
9001        2013-10-01  0
9001        2013-11-01  0
9001        2013-12-01  0
9001        2014-01-01  1
9001        2014-02-01  1
9001        2014-03-01  0
9001        2014-04-01  0
9001        2014-05-01  0
9001        2014-06-01  0
9001        2014-07-01  0
9001        2014-08-01  0
9001        2014-09-01  1
9001        2014-10-01  1
9001        2014-11-01  1
9001        2014-12-01  1
9002        2013-01-01  0
9002        2013-02-01  0
9002        2013-03-01  0
9002        2013-04-01  1
9002        2013-05-01  1
9002        2013-06-01  1
9002        2013-07-01  0
9002        2013-08-01  1
9002        2013-09-01  0
9002        2013-10-01  1
9002        2013-11-01  1
9002        2013-12-01  1
9002        2014-01-01  1
9002        2014-02-01  0
9002        2014-03-01  0
9002        2014-04-01  0
9002        2014-05-01  0
9002        2014-06-01  0
9002        2014-07-01  1
9002        2014-08-01  1
9002        2014-09-01  1
9002        2014-10-01  0
9002        2014-11-01  1
9002        2014-12-01  0

所需的输出:

CustomerID  Reportdate  True_False  Sequence
9001        2013-01-01  0           1 
9001        2013-02-01  0           2
9001        2013-03-01  0           3
9001        2013-04-01  1           0
9001        2013-05-01  0           1
9001        2013-06-01  1           0
9001        2013-07-01  1           0
9001        2013-08-01  0           1
9001        2013-09-01  1           0
9001        2013-10-01  0           1
9001        2013-11-01  0           2
9001        2013-12-01  0           3 
9001        2014-01-01  1           0
9001        2014-02-01  1           0
9001        2014-03-01  0           1
9001        2014-04-01  0           2
9001        2014-05-01  0           3 
9001        2014-06-01  0           4
9001        2014-07-01  0           5 
9001        2014-08-01  0           6
9001        2014-09-01  1           0
9001        2014-10-01  1           0
9001        2014-11-01  1           0
9001        2014-12-01  1           0
9002        2013-01-01  0           1
9002        2013-02-01  0           2
9002        2013-03-01  0           3
9002        2013-04-01  1           0
9002        2013-05-01  1           0
9002        2013-06-01  1           0
9002        2013-07-01  0           1
9002        2013-08-01  1           0
9002        2013-09-01  0           1
9002        2013-10-01  1           0
9002        2013-11-01  1           0
9002        2013-12-01  1           0
9002        2014-01-01  1           0
9002        2014-02-01  0           1
9002        2014-03-01  0           2
9002        2014-04-01  0           3
9002        2014-05-01  0           4  
9002        2014-06-01  0           5
9002        2014-07-01  1           0
9002        2014-08-01  1           0
9002        2014-09-01  1           0
9002        2014-10-01  0           1
9002        2014-11-01  1           0
9002        2014-12-01  0           1

因此序列字段将其操作数增加1,其中" True_False"为0然后停在" True_False"为1并随后重复增量以创建所需输出中显示的序列。

欢迎所有帮助,

 CREATE TABLE test (
    CustomerID bigint,
    DateKey date,
    True_false bit,

);

insert into test 
values 
     (9001,'2013-01-01','1'),
     (9001,'2013-02-01','0'),
     (9001,'2013-03-01','0'),
     (9001,'2013-04-01','0'),
     (9001,'2013-05-01','1'),
     (9001,'2013-06-01','1'),
     (9001,'2013-07-01','0'),
     (9001,'2013-08-01','0'),
     (9001,'2013-09-01','0'),
     (9001,'2013-10-01','0'),
     (9001,'2013-11-01','0'),
     (9001,'2013-12-01','1'),
     (9001,'2014-01-01','1'),
     (9001,'2014-02-01','0'),
     (9001,'2014-03-01','1'),
     (9001,'2014-04-01','0'),
     (9001,'2014-05-01','0'),
     (9001,'2014-06-01','1'),
     (9001,'2014-07-01','1'),
     (9001,'2014-08-01','0'),
     (9001,'2014-09-01','1'),
     (9001,'2014-10-01','0'),
     (9002,'2014-11-01','0'),
     (9002,'2014-12-01','0'),
     (9002,'2013-01-01','0'),
     (9002,'2013-02-01','0'),
     (9002,'2013-03-01','0'),
     (9002,'2013-04-01','1'),
     (9002,'2013-05-01','1'),
     (9002,'2013-06-01','0'),
     (9002,'2013-07-01','1'),
     (9002,'2013-08-01','1'),
     (9002,'2013-09-01','1'),
     (9002,'2013-10-01','1'),
     (9002,'2013-11-01','0'),
     (9002,'2013-12-01','1'),
     (9002,'2014-01-01','1'),
     (9002,'2014-02-01','0'),
     (9002,'2014-03-01','1'),
     (9002,'2014-04-01','1'),
     (9002,'2014-05-01','1'),
     (9002,'2014-06-01','0'),
     (9002,'2014-07-01','1'),
     (9002,'2014-08-01','1'),
     (9002,'2014-09-01','0'),
     (9002,'2014-10-01','0'),
     (9002,'2014-11-01','0'),
     (9002,'2014-12-01','0')

4 个答案:

答案 0 :(得分:4)

这应该可以解决问题:

declare @t table (CustomerID int, Reportdate date, True_False int)
insert @t values 
(9001,        '2013-01-01',  0),
(9001,        '2013-02-01',  0),
(9001,        '2013-03-01',  0),
(9001,        '2013-04-01',  1),
(9001,        '2013-05-01',  0),
(9001,        '2013-06-01',  1),
(9001,        '2013-07-01',  1),
(9001,        '2013-08-01',  0),
(9001,        '2013-09-01',  1),
(9001,        '2013-10-01',  0),
(9001,        '2013-11-01',  0),
(9001,        '2013-12-01',  0),
(9001,        '2014-01-01',  1),
(9001,        '2014-02-01',  1),
(9001,        '2014-03-01',  0),
(9001,        '2014-04-01',  0),
(9001,        '2014-05-01',  0),
(9001,        '2014-06-01',  0),
(9001,        '2014-07-01',  0),
(9001,        '2014-08-01',  0),
(9001,        '2014-09-01',  1),
(9001,        '2014-10-01',  1),
(9001,        '2014-11-01',  1),
(9001,        '2014-12-01',  1),
(9002,        '2013-01-01',  0),
(9002,        '2013-02-01' , 0),
(9002,        '2013-03-01' , 0),
(9002,        '2013-04-01',  1),
(9002,        '2013-05-01' , 1),
(9002,        '2013-06-01'  ,1),
(9002,        '2013-07-01',  0),
(9002,        '2013-08-01',  1),
(9002,        '2013-09-01',  0),
(9002,        '2013-10-01',  1),
(9002,        '2013-11-01',  1),
(9002,        '2013-12-01',  1),
(9002,        '2014-01-01',  1),
(9002,        '2014-02-01',  0),
(9002,        '2014-03-01',  0),
(9002,        '2014-04-01',  0),
(9002,        '2014-05-01',  0),
(9002,        '2014-06-01',  0),
(9002,        '2014-07-01',  1),
(9002,        '2014-08-01',  1),
(9002,        '2014-09-01',  1),
(9002,        '2014-10-01',  0),
(9002,        '2014-11-01',  1),
(9002,        '2014-12-01',  0)

;with x as (
select *, sum(true_false) over(partition by customerid order by reportdate) g
from @t
)
select customerid, reportdate, row_number() over(partition by customerid, g order by reportdate) - case when g = 0 then 0 else 1 end seq
from x

答案 1 :(得分:0)

希望这有助于, 该解决方案提供了OP

所要求的精确结果
;WITH cteResultset(CustomerID ,DateKey, True_false) AS
(
SELECT 9001,CAST('2013-01-01' AS DATE),CAST(0 AS BIT) UNION ALL
SELECT 9001,'2013-02-01',0 UNION ALL
SELECT 9001,'2013-03-01',0 UNION ALL
SELECT 9001,'2013-04-01',1 UNION ALL
SELECT 9001,'2013-05-01',0 UNION ALL
SELECT 9001,'2013-06-01',1 UNION ALL
SELECT 9001,'2013-07-01',1 UNION ALL
SELECT 9001,'2013-08-01',0 UNION ALL
SELECT 9001,'2013-09-01',1 UNION ALL
SELECT 9001,'2013-10-01',0 UNION ALL
SELECT 9001,'2013-11-01',0 UNION ALL
SELECT 9001,'2013-12-01',0 UNION ALL
SELECT 9001,'2014-01-01',1 UNION ALL
SELECT 9001,'2014-02-01',1 UNION ALL
SELECT 9001,'2014-03-01',0 UNION ALL
SELECT 9001,'2014-04-01',0 UNION ALL
SELECT 9001,'2014-05-01',0 UNION ALL
SELECT 9001,'2014-06-01',0 UNION ALL
SELECT 9001,'2014-07-01',0 UNION ALL
SELECT 9001,'2014-08-01',0 UNION ALL
SELECT 9001,'2014-09-01',1 UNION ALL
SELECT 9001,'2014-10-01',1 UNION ALL
SELECT 9001,'2014-11-01',1 UNION ALL
SELECT 9001,'2014-12-01',1 UNION ALL
SELECT 9002,'2013-01-01',0 UNION ALL
SELECT 9002,'2013-02-01',0 UNION ALL
SELECT 9002,'2013-03-01',0 UNION ALL
SELECT 9002,'2013-04-01',1 UNION ALL
SELECT 9002,'2013-05-01',1 UNION ALL
SELECT 9002,'2013-06-01',1 UNION ALL
SELECT 9002,'2013-07-01',0 UNION ALL
SELECT 9002,'2013-08-01',1 UNION ALL
SELECT 9002,'2013-09-01',0 UNION ALL
SELECT 9002,'2013-10-01',1 UNION ALL
SELECT 9002,'2013-11-01',1 UNION ALL
SELECT 9002,'2013-12-01',1 UNION ALL
SELECT 9002,'2014-01-01',1 UNION ALL
SELECT 9002,'2014-02-01',0 UNION ALL
SELECT 9002,'2014-03-01',0 UNION ALL
SELECT 9002,'2014-04-01',0 UNION ALL
SELECT 9002,'2014-05-01',0 UNION ALL
SELECT 9002,'2014-06-01',0 UNION ALL
SELECT 9002,'2014-07-01',1 UNION ALL
SELECT 9002,'2014-08-01',1 UNION ALL
SELECT 9002,'2014-09-01',1 UNION ALL
SELECT 9002,'2014-10-01',0 UNION ALL
SELECT 9002,'2014-11-01',1 UNION ALL
SELECT 9002,'2014-12-01',0
),cte_Sequence AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS Id,*
FROM cteResultset ),
    cte AS (
        SELECT Id,
            CustomerID,
            DateKey,
            True_false,
            True_false AS Part
        FROM cte_Sequence
        WHERE id = 1

        UNION ALL

        SELECT a.Id,
            a.CustomerID,
            a.DateKey,
            a.True_false,
            cte.Part + a.True_false
        FROM cte
        INNER JOIN cte_Sequence a
            ON cte.id + 1 = a.id
        )

SELECT Id,CustomerID,
    DateKey,
    True_false,
    row_number() OVER (
        PARTITION BY CustomerID,
        Part ORDER BY DateKey
        ) AS Sequence
FROM cte
WHERE True_false = 0
UNION 
SELECT id,CustomerID,
    DateKey,
    True_false,
    0 AS Sequence
FROM cte
WHERE True_false = 1
ORDER BY Id
OPTION (MAXRECURSION 32767);

输出:

Id  CustomerID  DateKey     True_false  Sequence
1   9001        2013-01-01  0           1
2   9001        2013-02-01  0           2
3   9001        2013-03-01  0           3
4   9001        2013-04-01  1           0
5   9001        2013-05-01  0           1
6   9001        2013-06-01  1           0
7   9001        2013-07-01  1           0
8   9001        2013-08-01  0           1
9   9001        2013-09-01  1           0
10  9001        2013-10-01  0           1
11  9001        2013-11-01  0           2
12  9001        2013-12-01  0           3
13  9001        2014-01-01  1           0
14  9001        2014-02-01  1           0
15  9001        2014-03-01  0           1
16  9001        2014-04-01  0           2
17  9001        2014-05-01  0           3
18  9001        2014-06-01  0           4
19  9001        2014-07-01  0           5
20  9001        2014-08-01  0           6
21  9001        2014-09-01  1           0
22  9001        2014-10-01  1           0
23  9001        2014-11-01  1           0
24  9001        2014-12-01  1           0
25  9002        2013-01-01  0           1
26  9002        2013-02-01  0           2
27  9002        2013-03-01  0           3
28  9002        2013-04-01  1           0
29  9002        2013-05-01  1           0
30  9002        2013-06-01  1           0
31  9002        2013-07-01  0           1
32  9002        2013-08-01  1           0
33  9002        2013-09-01  0           1
34  9002        2013-10-01  1           0
35  9002        2013-11-01  1           0
36  9002        2013-12-01  1           0
37  9002        2014-01-01  1           0
38  9002        2014-02-01  0           1
39  9002        2014-03-01  0           2
40  9002        2014-04-01  0           3
41  9002        2014-05-01  0           4
42  9002        2014-06-01  0           5
43  9002        2014-07-01  1           0
44  9002        2014-08-01  1           0
45  9002        2014-09-01  1           0
46  9002        2014-10-01  0           1
47  9002        2014-11-01  1           0
48  9002        2014-12-01  0           1

答案 2 :(得分:0)

这可以使用标识列和while循环,这里我使用临时表编写。

select * into #temp from test

ALTER TABLE #temp
ADD ID INT IDENTITY(1,1)

ALTER TABLE #temp
ADD Sequence INT

DECLARE @Min INT,@Max INT,@COUNT INT
SET @Min=1
SET @COUNT=1  
SELECT @Max=COUNT(1) FROM test

WHILE(@Min<=@Max)
BEGIN
 IF((SELECT True_false FROM #temp WHERE ID=@Min)=0)
    BEGIN
        update  #temp set Sequence=@COUNT WHERE ID=@Min
        SET @COUNT=@COUNT+1
    END
 ELSE
    BEGIN
        update  #temp set Sequence=0 WHERE ID=@Min
        SET @COUNT=1
    END
SET @Min=@Min+1
END
SELECT * FROM #temp

答案 3 :(得分:-1)

您可以使用窗口函数和来计算运行总计,如下所示

;with cte as (
select *, sum(True_false) over(partition by customerid order by ReportDate) TF from #customer
)
select *, [Sequence] = row_number() over (partition by Customerid, TF order by TF) - 1 from cte