2016-11-23 1 views
0
n | g 
--------- 
    1 | 1 
    2 | NULL 
    3 | 1 
    4 | 1 
    5 | 1 
    6 | 1 
    7 | NULL 
    8 | NULL 
    9 | NULL 
10 | 1 
11 | 1 
12 | 1 
13 | 1 
14 | 1 
15 | 1 
16 | 1 
17 | NULL 
18 | 1 
19 | 1 
20 | 1 
21 | NULL 
22 | 1 
23 | 1 
24 | 1 
25 | 1 
26 | NULL 
27 | NULL 
28 | 1 
29 | 1 
30 | NULL 
31 | 1 

Dans la colonne ci-dessus g je devrais obtenir ce résultat:Compter les groupes de valeurs NULL - partition ou fenêtre?

x|y 
--- 
1|4 
2|1 
3|1 

x représente le nombre de NULLs contigus et
y représente le temps d'un seul groupe de NULLs se produit .

Ie, il y a ...
4 groupes de seulement 1 NULL,
une série de 2 NULLs et
1 groupe de 3 NULLs

Répondre

1

Compute Un compte courant des valeurs non nulles avec une fonction de fenêtre pour former des groupes, puis 2 deux chefs d'accusation imbriqués ...

SELECT x, count(*) AS y 
FROM (
    SELECT grp, count(*) FILTER (WHERE g IS NULL) AS x 
    FROM (
     SELECT g, count(g) OVER (ORDER BY n) AS grp 
     FROM tbl 
    ) sub1 
    WHERE g IS NULL 
    GROUP BY grp 
    ) sub2 
GROUP BY 1 
ORDER BY 1; 

count() ne compte que des valeurs non nulles.

Ceci inclut la ligne précédente avec une valeur non nulle g dans le groupe suivant (grp) de valeurs NULL - qui doit être supprimée du nombre.

J'ai remplacé la clause HAVING que j'avais pour cela dans ma requête initiale avec WHERE g IS NULL, comme @klin uses in his answer), c'est plus simple.

connexes:

Sin est une séquence gapless des nombres entiers, vous pouvez simplifier:

SELECT x, count(*) AS y 
FROM (
    SELECT grp, count(*) AS x 
    FROM (
     SELECT n - row_number() OVER (ORDER BY n) AS grp 
     FROM tbl 
     WHERE g IS NULL 
    ) sub1 
    GROUP BY 1 
    ) sub2 
GROUP BY 1 
ORDER BY 1; 

Éliminez pas les valeurs NULL immédiatement et déduisent le numéro de ligne de n, arrivant ainsi à (sans signification) les numéros de groupe directement ...


Alors que la seule valeur possible g est 1, sum() est un truc intelligent (like @klin provided). Mais cela devrait être une colonne boolean alors, n'aurait pas de sens en tant que type numérique. Donc, je suppose que c'est juste une simplification du problème réel dans la question.

+0

Cela a été très utile, merci –

0
select x, count(x) y 
from (
    select s, count(s) x 
    from ( 
     select *, sum(g) over (order by i) as s 
     from example 
     ) s 
    where g isnull 
    group by 1 
    ) s 
group by 1 
order by 1; 

Test it here.