2016-05-15 12 views
2

sagen, dass ich mehrere Zeilen (nach Datum sortiert), von denen eine Spalte enthält folgende Daten:SQL - Prädikat auf einer geordneten Reihe von Zahlen

1 
1 
1 
0 
0 
1 
0 
1 
1 
1 

usw. Wie kann ich die Anzahl der 1s bis zum nächsten wählen 0 erreicht ist, danach den Zähler zurücksetzen. Zum Beispiel sollte die Abfrage folgende Daten zurück:

1 
1 
1 3 
0 
0 
1 1 
0 
1 
1 
1 3 

Eigentlich brauche ich nicht unbedingt die Daten, ich bin in Ordnung, wenn die Abfrage nur Aggregat/Anzahl zurückzugibt. Ich habe gerade die erste Spalte hinzugefügt, um das Verständnis zu erleichtern. Ich benutze PostgreSQL 9.5. Es wäre jedoch interessant, wie dieses Problem auch für andere DBs gelöst werden kann.

Dank

+0

gibt es eine andere Spalte die Reihenfolge festlegen, ist? –

+0

Hallo, ja, etwas wie ORDER BY Date – Davita

+1

Sie benötigen eine Spalte, die die Reihenfolge angibt. Standardmäßig sind SQL-Tabellen ungeordnet. –

Antwort

1

In diesem SQL gehe ich davon aus Spalte c1 eine Sequenz für die Tage

drop table if exists t5; 
create table t5 (c1 int primary key, c2 int); 

insert into t5 values (1, 1); 
insert into t5 values (2, 1); 
insert into t5 values (3, 1); 
insert into t5 values (4, 0); 
insert into t5 values (5, 0); 
insert into t5 values (6, 1); 
insert into t5 values (7, 0); 
insert into t5 values (8, 1); 
insert into t5 values (9, 1); 
insert into t5 values (10, 1); 

select grp, max(cnt) from (
    with recursive t(id, cnt, grp) as (
     select c1, c2, 1 
     from t5 
     where c1 = 1 
     union all 
     select c1, 
       -- if next is 1 increment existing count else set it to zero 
       case when b.c2 = 1 then cnt+1 else 0 end, 
       -- if 0 change group else retain group [0 to 1 will retain group] 
       -- as long as '1' to '0' changes the group we are good 
       case when b.c2 = 1 then grp else grp+1 end 
     from t5 b, t 
     where b.c1 = id + 1 
    ) 
    select * from t 
) t group by grp having max(cnt) > 0 order by grp 

OUTPUT enter image description here

0

Hier ist eine Teillösung für SQL Server 2008 R2, sondern auf andere Datenbanken implementieren sollten. ones ist Ihre ursprüngliche Tabelle mit einem id Schlüsselfeld, das die Reihenfolge der Daten (1, 2, 3 usw.) widerspiegelt. flag enthält die Einträge 1 und 0 Einträge. Es gruppiert die Daten durch Zählen von Zeilen mit Flag = 0, die vor jeder Zeile erscheinen. Bei jedem Lauf von 1 wird eine steigende Anzahl von Nullen davor gezählt. Sie können damit jeden Lauf von 1 eindeutig identifizieren. Es bietet keine laufende Zählung, aber gibt Ihnen eine Zusammenfassung Anzahl für jeden Lauf von 1 s.

create table ones_summary (PreviousZeros int) 

insert ones_summary 
select (select count(*) as N from ones t2 where t2.id < t1.id and t2.flag = 0) as PreviousZeros 
from ones t1 
where t1.flag = 1 

select PreviousZeros, count(*) 
from ones_summary 
group by PreviousZeros 
Verwandte Themen