2017-07-27 5 views
0

Cela ressemble à un problème d'espaces et d'îlots et les fonctions de fenêtre semblent être le bon outil, mais je n'arrive pas à obtenir un résultat fonctionnel.Trouver les lignes menant à un événement et les traiter comme une séquence

Mes données ressemble à ceci (Note: gameid est un UUID et montré ici comme un compteur pour la lisibilité):

GameID User Date  Win 

    100  A 10/11/2012 0 
    101  A 10/12/2012 0 
    102  B 10/11/2012 0 
    103  B 10/13/2012 1 
    104  B 10/14/2012 0 
    105  C 10/10/2012 0 
    106  C 10/12/2012 0 
    107  C 10/13/2012 1 
    108  C 10/14/2012 0 
    109  C 10/15/2012 0 
    110  C 10/16/2012 0 
    111  C 10/17/2012 1 
    112  D 10/11/2012 0 
    113  D 10/13/2012 1 
    114  D 10/20/2012 0 
    115  D 10/21/2012 0 

Je cherche à capturer (compte/total dans un tableau) la séquence des pertes un utilisateur a avant chaque victoire. Par exemple, si vous regardez l'utilisateur B, ils ont une victoire, cette victoire a une perte avant. Si vous regardez l'utilisateur C, la victoire avec l'ID 107 est précédée de deux pertes et la victoire avec l'ID 111 est précédée de 3 pertes.

Je cherche à appliquer l'agrégation de tableau array_agg et attacher les pertes précédentes à une victoire. En fin de compte, je veux que le résultat suivant:

GameID User Date  Win LosingStreak 


    103  B 10/13/2012 1 [102] 
    107  C 10/13/2012 1 [105, 106] 
    111  C 10/17/2012 1 [110,109,108] 
    113  D 10/13/2012 1 [112] 

Je joue avec partition by User order by date mais je dois « reset » chaque partition à une victoire et je ne peux pas sembler envelopper la tête autour d'une façon de le résoudre. lead() et lag() ne sont d'ailleurs d'aucune aide car j'ai besoin du lead (x) où x est un nombre variable pour chaque partition.

Répondre

1

Hmmm. Vous pouvez identifier les groupes en utilisant une somme inverse des gains. Ensuite, faites simplement l'agrégation:

select t.user, max(t.date) as date, 
     max(case when win = 1 then gameid end) as gameid, 
     array_agg(gameid order by date asc) filter (where win = 0) as gameid_losses 
from (select t.*, 
      sum(wins) over (partition by user order by date desc) as grp 
     from t 
    ) t 
group by user, grp; 
+0

Très intelligent. Merci beaucoup. – maxTrialfire