2016-11-24 60 views
0

计数器我有这样的情况 -如何提高选择

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列中的数字加1。我想在选择中有这个。我不能使用循环。

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

+3

没有ID列或时间戳或类似的? – jarlh

回答

4

使用cte和window函数Row_Number()...但是,我应该注意,如果在OVER子句中用正确的顺序(即identity int,datetime)替换(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 
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 | 
+----+---+-------+ 
+0

也是我的第一选择。然而,OP是2008 –

+0

就像@JohnCappelletti提到的那样,这在2008R2中是不可用的,但它从2012年开始可用,所以,是的.. –

+0

根据https://msdn.microsoft.com/en-us/library/ ms189461.aspx它可从2008年(我明确检查)... – HoneyBadger

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;