J'ai les données suivantes que je souhaite sélectionner comme suit:
Comment puis-je modifier la requête pour sélectionner la sortie comme indiqué ci-dessous? primary_id timestamp secondary_id attribute1 attribute2 ... -- I want to get
-------------------------------------------------------------------
1 2020/01/20 10 ... ... ... -- <- this
2 2020/02/28 10 ... ... ...
3 2020/03/01 10 ... ... ... -- <- and this
4 2020/04/08 20 ... ... ... -- <- this
5 2020/05/31 20 ... ... ...
6 2020/06/30 20 ... ... ...
7 2020/06/31 20 ... ... ...
8 2020/07/31 20 ... ... ... -- <- and this
4 Réponses :
Vous pouvez utiliser les fonctions de fenêtre pour classer des enregistrements ayant le même secondaire_id code> par ascension et décroissant
horodatage code>, puis utilisez ces informations pour filtrer dans le premier et dernier enregistrement par groupe :
select primary_id, timestamp, secondary_id, ...
from (
select
t.*,
row_number() over(partition by secondary_id order by timestamp asc ) rn_asc,
row_number() over(partition by secondary_id order by timestamp desc) rn_desc
from tablename t
where
timestamp <= timestamp '2020-07-29 00:00:00'
and timestamp < timestamp '2020-07-29 04:00:00'
) t
where 1 in (rn_asc, rn_desc)
order by timestamp, secondary_id;
Merci pour l'aide et la réponse rapides, GMB.I a essayé la requête ci-dessus, mais cela prend très longtemps. D'autre part, la requête que j'ai écrite précédemment ne prend que quelques secondes. Des idées sur la façon d'optimiser cette requête? Actuellement, il serait plus rapide pour moi de récupérer l'ensemble du jeu de données en Java et de la filtrer là-bas avec la fréquence de la requête ci-dessus. Je voudrais filtrer cela à l'extrémité Oracle. Par conséquent, toute aide serait grandement appréciée
Bienvenue @jared. Si ma réponse répondit correctement à votre question, alors Acceptez-le en cliquant sur le panneau. Merci.
Veuillez utiliser ci-dessous Query,
select primary_id, timestamp, secondary_id,... from (select primary_id, timestamp, secondary_id,..., row_number() over (partition by secondary_id order by timestamp) as rnk1, row_number() over (partition by secondary_id order by timestamp desc) as rnk2 from tablename where timestamp <= to_timestamp('2020-07-29 00:00:00', 'YYYY-MM-DD HH24:MI:SS') and timestamp < to_timestamp('2020-07-29 04:00:00', 'YYYY-MM-DD HH24:MI:SS') ) qry where rnk1=1 and rnk2 = 1 order by timestamp, secondary_id;
Merci Jim. Vraiment apprécier l'aide rapide et la réponse
Vous pouvez utiliser first_value strong> et last_value strong>. Ce sont des fonctions d'analyse et peuvent être utilisées comme dans la démo ci-dessous.
Merci giliam
@Jared: Est-ce que cela fonctionne pour vous et / ou avez-vous résolu le problème?
Cela fonctionne également lorsque la valeur de secondaire_id peut être répétée dans un autre groupe de lignes, elle vérifie simplement si l'ID actuel est différent de la ligne précédente ou suivante:
select * from ( select t.*, lag(secondary_id) over(order by timestamp asc ) lag_id, lead(secondary_id) over(order by timestamp asc) lead_id from tablename t where timestamp <= timestamp '2020-07-29 00:00:00' and timestamp < timestamp '2020-07-29 04:00:00' ) t where lag_id is null or lead_id is null or lag_id <> secondary_id or lead_id <> secondary_id order by timestamp, secondary_id;
Pourriez-vous s'il vous plaît expliquer clairement? Pouvez-vous publier vos données et résultat attendu aussi
Chacun défini dans le sens, vous avez besoin de secondaire_id?