2017-10-06 2 views
0

Je veux donner le rang au-dessous des données en fonction du temps (si la différence d'horodatage est moins les 15 minutes alors même rang rang d'autre +1) Par exempleet lui a donné les rangs en fonction de certaines conditions

  • temps: 06:10:32 et 06:12:38 devrait obtenir le rang 1
  • heure: 13:36:44 et 13:40:41 et 13:44:47 devrait obtenir le rang 2
  • et les 4 dernières lignes devraient obtenir rang 3
user_id ride_id  createdat_local  
2681233 96783742 2017-10-04 06:10:32 
2681233 96784171 2017-10-04 06:12:38 
2681233 96924751 2017-10-04 13:36:44 
2681233 96925561 2017-10-04 13:40:41 
2681233 96926560 2017-10-04 13:44:47 
2681233 96994651 2017-10-04 18:12:29 
2681233 96995953 2017-10-04 18:18:16 
2681233 96996937 2017-10-04 18:22:15 
2681233 96997195 2017-10-04 18:24:00 
+0

Quels sont les dbms que vous utilisez? Ne pas étiqueter les produits non concernés. – jarlh

+0

Est-ce sql-server ou postgresql? –

+0

J'ai supprimé les types de base de données incompatibles. Veuillez ne marquer que la base de données que vous utilisez réellement. –

Répondre

2

Dans SQL Server 2012+:

Utilisation de la fonction de fenêtre lag() dans un common table expression pour obtenir le datediff() par rapport à la valeur précédente de ligne pour createdat_local, puis sum() over() avec agrégation conditionnelle pour générer le rang:

;with cte as (
select * 
    , datediff(minute,lag(createdat_local) over (
     partition by user_id 
     order by createdat_local 
    ),createdat_local) as prev_dat 
from t 
) 
select user_id, ride_id, createdat_local 
    , sum(case when coalesce(prev_dat,16)>15 then 1 else 0 end) over (
    partition by user_id 
    order by createdat_local 
    ) as rank 
from cte 

rextester demo: http://rextester.com/EQUC48356

retours:

+---------+----------+---------------------+------+ 
| user_id | ride_id | createdat_local | rank | 
+---------+----------+---------------------+------+ 
| 2681233 | 96783742 | 2017-10-04 06:10:32 | 1 | 
| 2681233 | 96784171 | 2017-10-04 06:12:38 | 1 | 
| 2681233 | 96924751 | 2017-10-04 13:36:44 | 2 | 
| 2681233 | 96925561 | 2017-10-04 13:40:41 | 2 | 
| 2681233 | 96926560 | 2017-10-04 13:44:47 | 2 | 
| 2681233 | 96994651 | 2017-10-04 18:12:29 | 3 | 
| 2681233 | 96995953 | 2017-10-04 18:18:16 | 3 | 
| 2681233 | 96996937 | 2017-10-04 18:22:15 | 3 | 
| 2681233 | 96997195 | 2017-10-04 18:24:00 | 3 | 
+---------+----------+---------------------+------+ 
+0

Merci SqlZim, avec votre logique, je suis en mesure d'atteindre le même résultat en redshift – user2207709

+0

@ user2207709 Joyeux d'aider! – SqlZim

0

Capable d'atteindre le résultat requis redshift (psql)

Requête: avec cte comme ( select *, (DATEPART ('heure', createdat_local) * 60 + DATEPART ('minute' , createdat_local)) - lag (DATEPART ('heure', createdat_local) * 60 + DATEPART ('minute', createdat_local) ) sur (partition par ordre user_id par createdat_local) comme diff_in_minutes de t ) select user_id, ride_id , createdat_local , sum (cas quand coalesce (diff_in_minutes, 16)> 15 puis 1 sinon 0 fin) o ver ( partition par user_id ordre par createdat_local lignes entre la ligne précédente et la ligne courante non bornées ) comme rang de cte;