2016-11-24 5 views
0

Ich habe diese Art von Situation zu erhöhen -Wie Zähler in ausgewählten

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

ich so etwas wie this- für jedes Vorkommen von 1 in Spalte A

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 

Es ist wie wollen wir die steigen Nummer in Spalte B um eins. Ich möchte dies in einer Auswahl haben. Ich kann dafür keine Schleife verwenden.

Ich benutze SQL-Server 2008 R2. Kann mir bitte jemand eine Idee geben wie es gemacht werden kann. Danke im Voraus.

+3

Keine id Spalte oder einen Zeitstempel oder ähnliches? – jarlh

Antwort

4

Mit einer Cte- und Fensterfunktion Row_Number() ... Allerdings sollte ich beachten, dass es am besten wäre, wenn Sie in der OVER-Klausel (Select NULL) durch eine richtige Sequenz ersetzen (zB identity int, datetime).

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 

Returns

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

Sie müssen etwas bestellen. Angenommen, Sie haben eine 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) 

Ergebnis:

+------+---+-------+ 
| 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 | 
+------+---+-------+ 

edit: Die oben ist nur von SQL Server 2012, für frühere Ausgaben sollten folgende Arbeiten:

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 

Ergebnis:

+----+---+-------+ 
| 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

Wäre meine erste Wahl auch. Allerdings ist OP 2008 –

+0

Genau wie @JohnCappelletti erwähnt, ist dies nicht in 2008R2 verfügbar, aber es ist ab 2012 verfügbar, so, ja .. –

+0

Nach https://msdn.microsoft.com/en-us/library/ ms189461.aspx es ist ab 2008 verfügbar (ich habe es ausdrücklich überprüft) ... – HoneyBadger

0

Erstens können Sie nicht tun, was Sie wollen, weil Ihr Ergebnis auf der Reihenfolge der Zeilen in der Tabelle abhängt. Denken Sie daran: SQL-Tabellen repräsentieren ungeordnete Sets; Es gibt keine Reihenfolge, es sei denn, eine Spalte macht dies explizit.

Wenn Sie eine Bestellung Spalte haben, dann denken die einfachste Methode in SQL Server 2008 ist eine korrelierte Unterabfrage oder 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;