J'ai un ensemble de données qui a ID, datetime + tas de champs de valeur.Tous les enregistrements à moins d'une heure les uns des autres
L'idée est que les enregistrements sont à moins d'une heure l'un de l'autre sont une session. Il ne peut y avoir qu'une session toutes les 24 heures. (L'heure est mesurée à partir du début du premier enregistrement)
L'approche de jour() ne fonctionne pas car un enregistrement peut être 23:55 et le suivant pourrait être 00:01 le jour suivant et il serait la même session.
J'ai ajouté rowid et couru les éléments suivants:
data testing;
set testing;
by subscriber_no;
prev_dt = lag(record_ts);
prev_row = lag(rowid);
time_from_last = intck("Second",record_ts,prev_dt);
if intck("Second",record_ts,prev_dt) > -60*60 and intck("Second",record_ts,prev_dt) < 0 then
same_session = 'yes';
else same_session = 'no';
if intck("Second",record_ts,prev_dt) > -60*60 and intck("Second",record_ts,prev_dt) < 0 then
rowid = prev_row;
else rowid = rowid;
format prev_dt datetime19.;
output;
run;
fichier d'entrée d'entrée
ID record_TS rowid
52 17MAY2017:06:24:28 4
52 17MAY2017:07:16:12 5
91 05APR2017:07:04:55 6
91 05APR2017:07:23:37 7
91 05APR2017:08:04:52 8
91 05MAY2017:08:56:23 9
est triée par ID et enregistrer TS.
La sortie était
ID record_TS rowid prev_dt prev_row time_from_last same_session
52 17MAY2017:06:24:28 4 28APR2017:08:51:25 3 -1632783 no
52 17MAY2017:07:16:12 4 17MAY2017:06:24:28 4 -3104 yes
91 05APR2017:07:04:55 6 17MAY2017:07:16:12 5 3629477 no
91 05APR2017:07:23:37 6 05APR2017:07:04:55 6 -1122 yes
91 05APR2017:08:04:52 7 05APR2017:07:23:37 7 -2475 yes This needs to be 6
91 05MAY2017:08:56:23 9 05APR2017:08:04:52 8 -2595091 no
Deuxième rangée du bas - rowid sort 7, alors que je besoin de venir être 6.
Fondamentalement, je dois changer la rowid actuelle enregistrée avant la le script se déplace pour évaluer le suivant.
Merci Ben
J'ai réalisé ce que je avais besoin avec
proc sql;
create table testing2 as
select distinct t1.*, min(t2.record_TS) format datetime19. as from_time, max(t2.record_TS) format datetime19. as to_time
from testing t1
join testing t2 on t1.id_val= t2.id_val
and intck("Second",t1.record_ts,t2.record_ts) between -3600 and 3600
group by t1.id_val, t1.record_ts
order by t1.id_val, t1.record_ts
;
quit;
Mais je me demande encore s'il y a un moyen de valider les modifications à la ligne courante avant de passer à la prochaine évaluation rangée.
Pourquoi ne pas simplement créer une table "session", ont une ligne par session et défini une date 'ExpiresAt' qui est de 24 heures dans l'avenir. Ensuite, chaque fois qu'un utilisateur fait une demande, mettez 'ExpiresAt' à jour dans 24 heures. – Basic
C'est ce que j'essaie de faire. Je ne peux pas changer la structure de la table source ni les données disponibles. – Ben
Pouvez-vous ajouter vos données HAVE (c'est-à-dire l'ensemble de données en entrée) à la question? La variable subscriber_no est-elle ce qui est imprimé dans la sortie en tant qu'ID? Je remarque que vous avez une instruction BY BY subscriber_no, mais aucune logique pour empêcher deux abonnés différents d'être assignés à la même session. Généralement, c'est une mauvaise idée de faire en sorte que les jeux de données d'entrée et de sortie soient les mêmes, même en testant simplement, car il est difficile de répéter les tests et de vérifier les résultats. – Quentin