2016-02-04 2 views
2

Je m'excuse si cette question a déjà été posée, j'ai tenté une recherche mais je n'ai pas pu trouver de fil de discussion pertinent.Traitement des données séquentielles/ordonnées en SQL

J'ai reçu une source de données semi-volumineuse (~ 15m enregistrements) sur laquelle j'ai besoin d'effectuer une analyse pour déterminer le comportement de l'utilisateur. La source de données comprend des champs pour l'ID utilisateur, la date de la transaction et un indicateur pour indiquer si la transaction avait une certaine caractéristique. Évidemment, je simplifie ici pour aller au cœur de la question. Le nombre de transactions par utilisateur variera beaucoup (de 1 à 200+), la distribution des dates variera et la distribution des drapeaux variera.

Tenir compte le tableau suivant:

ID   User ID   Date    Flag 
1   1    2015-01-03  Y 
2   1    2015-03-15  N 
3   1    2015-07-20  N 
4   1    2015-11-18  N 
5   1    2015-11-29  N 
6   2    2015-02-16  Y 
7   2    2015-03-03  N 
8   2    2015-06-10  Y 
9   2    2015-08-10  Y 

Comment peut-on aller sur l'interrogation de ces données pour isoler les enregistrements en fonction des caractéristiques des autres enregistrements pour le même utilisateur avant ou après?

Par exemple:

  1. Comment peut-on identifier les enregistrements avec un drapeau « Y » qui sont suivies par trois autres dossiers (classés par date) pour le même ID utilisateur avec un drapeau « N »? [Renvoie 1 dans le tableau ci-dessus]

  2. Comment identifier les ID utilisateur lorsque 50% ou plus de leurs transactions avec les indicateurs «Y» se produisent dans les premiers 20% de leurs transactions? [Renvoyer l'ID utilisateur 1 dans le tableau ci-dessus]

J'espère que la question est suffisamment claire.

* Edit: La réponse ci-dessous est correcte, mais il ne savait pas que j'utilise MySQL comme base de données (j'ai ajouté dans le tag après avoir répondu). MySQL ne prend pas en charge ces fonctions, Oracle ou SQL Server pourraient implémenter ces fonctions.

+0

Veuillez marquer votre question avec la base de données que vous utilisez. –

Répondre

3

Cette question suppose une base de données raisonnable prenant en charge les fonctions fenêtre/analytique.

La première question peut être gérée à l'aide lead():

select t.* 
from (select t.*, 
      lead(flag, 1) over (partition by userid order by date) as flag_1, 
      lead(flag, 2) over (partition by userid order by date) as flag_2, 
      lead(flag, 3) over (partition by userid order by date) as flag_3 
     from t 
    ) t 
where flag = 'Y' and flag_1 = 'N' and flag_2 = 'N' and flag_3 = 'N'; 

La seconde utilise également des fonctions de fenêtre:

select user_id 
from (select t.*, 
      row_number() over (partition by user_id order by date) as seqnum, 
      count(*) over (partition by user_id) as cnt 
     from t 
    ) t 
group by user_id 
having sum(case when flag = 'Y' and seqnum/0.2 <= cnt then 1 else 0 end) >= 
      0.5 * sum(case when flag = 'Y' then 1 else 0 end); 

Ainsi, la réponse à votre question est essentiellement: En savoir plus sur la fenêtre (analytique) les fonctions.

+0

Très intéressant, je n'ai pas vu ces fonctions avant mais en lisant le SQL, je peux voir ce qu'ils doivent faire. La base de données est MySQL et après une recherche rapide sur Google, il semble que je n'aurai aucun problème à implémenter ceci. Vraiment apprécier la réponse rapide et détaillée. – SeaChange