0
votes

Comment puis-je sélectionner la première et la dernière ligne pour chaque ensemble renvoyé

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? XXX PRE>

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


2 commentaires

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?


4 Réponses :


3
votes

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;


2 commentaires

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.



0
votes

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;


1 commentaires

Merci Jim. Vraiment apprécier l'aide rapide et la réponse



0
votes

Vous pouvez utiliser first_value et last_value . Ce sont des fonctions d'analyse et peuvent être utilisées comme dans la démo ci-dessous. XXX


2 commentaires

Merci giliam


@Jared: Est-ce que cela fonctionne pour vous et / ou avez-vous résolu le problème?



2
votes

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;


0 commentaires