如何在选择中增加计数器

时间:2016-11-24 13:00:52

标签: sql sql-server sql-server-2008 tsql

我有这种情况 -

Column A
    1
    0
    0
    0
    1
    0
    0
    0
    0
    1
    0
    1
    0
    0 
    1
    0

我想要这样的东西 -

Column A                      Column B
    1                         1
    0                         1
    0                         1
    0                         1
    1                         2
    0                         2
    0                         2
    0                         2
    0                         2
    1                         3
    0                         3
    1                         4
    0                         4
    0                         4
    1                         5
    0                         5

对于A列中每次出现1的情况,我们将B列中的数字增加一。我希望在选择中有这个。我不能使用循环。

我正在使用SQL-Server 2008 R2。任何人都可以请你知道它是如何做到的。提前谢谢。

3 个答案:

答案 0 :(得分:4)

使用cte和window函数Row_Number()...但是,我应该注意,如果用适当的序列(即identity int,datetime)替换OVER子句中的(Select NULL),那将是最好的。

Declare @YourTable table (ColumnA int)
Insert Into @YourTable values (1),(0),(0),(0),(1),(0),(0),(0),(0),(1),(0),(1),(0),(0),(1),(0)

;with cte as (
    Select *,RN=Row_Number() over (Order By (Select Null)) from @YourTable
)
Select A.ColumnA
      ,ColumnB = sum(B.ColumnA)
 From  cte A
 Join  cte B on (B.RN<=A.RN)
 Group By A.ColumnA,A.RN
 Order By A.RN

返回

ColumnA ColumnB
1       1
0       1
0       1
0       1
1       2
0       2
0       2
0       2
0       2
1       3
0       3    
1       4
0       4
0       4
1       5
0       5

答案 1 :(得分:3)

你需要订购的东西。假设你有一个ID:

SELECT  *   
,       SUM(n) OVER(ORDER BY id)
FROM    ( VALUES (1, 1)
          ,      (2, 0)
          ,      (3, 0)
          ,      (4, 0)
          ,      (5, 1)
          ,      (6, 0)
          ,      (7, 0)
          ,      (8, 0)
          ,      (9, 0)
          ,      (10, 1)
          ,      (11, 0)
          ,      (12, 1)
          ,      (13, 0)
          ,      (14, 0)
          ,      (15, 1)
          ,      (16, 0) 
         ) x (id, n )

结果:

+------+---+-------+
| id   | n | total |
+------+---+-------+
|    1 | 1 |     1 |
|    2 | 0 |     1 |
|    3 | 0 |     1 |
|    4 | 0 |     1 |
|    5 | 1 |     2 |
|    6 | 0 |     2 |
|    7 | 0 |     2 |
|    8 | 0 |     2 |
|    9 | 0 |     2 |
|   10 | 1 |     3 |
|   11 | 0 |     3 |
|   12 | 1 |     4 |
|   13 | 0 |     4 |
|   14 | 0 |     4 |
|   15 | 1 |     5 |
|   16 | 0 |     5 |
+------+---+-------+

编辑:上述内容仅适用于sql server 2012,对于之前的版本,以下版本应有效:

WITH test AS
(
    SELECT  *
    FROM    ( VALUES (1, 1)
              ,      (2, 0)
              ,      (3, 0)
              ,      (4, 0)
              ,      (5, 1)
              ,      (6, 0)
              ,      (7, 0)
              ,      (8, 0)
              ,      (9, 0)
              ,      (10, 1)
              ,      (11, 0)
              ,      (12, 1)
              ,      (13, 0)
              ,      (14, 0)
              ,      (15, 1)
              ,      (16, 0) 
             ) x (id, n ) 
)

SELECT  a.id
,       a.n
,       SUM(b.n)
FROM    test a
LEFT JOIN test b
        ON b.id <= a.id
GROUP BY a.id
,        a.n

结果:

+----+---+-------+
| id | n | total |
+----+---+-------+
|  1 | 1 |     1 |
|  2 | 0 |     1 |
|  3 | 0 |     1 |
|  4 | 0 |     1 |
|  5 | 1 |     2 |
|  6 | 0 |     2 |
|  7 | 0 |     2 |
|  8 | 0 |     2 |
|  9 | 0 |     2 |
| 10 | 1 |     3 |
| 11 | 0 |     3 |
| 12 | 1 |     4 |
| 13 | 0 |     4 |
| 14 | 0 |     4 |
| 15 | 1 |     5 |
| 16 | 0 |     5 |
+----+---+-------+

答案 2 :(得分:0)

首先,你无法做你想做的事,因为你的结果取决于表中行的顺序。请记住:SQL表代表无序集;除非列明确说明,否则没有排序。

如果您有一个排序列,那么认为SQL Server 2008中最简单的方法是相关子查询或outer apply

select t.a, t2.b
from t outer apply
     (select count(*) as b
      from t t2
      where t2.id <= t.id and t2.a = 1
     ) t2;