dise que j'ai une table que j'interrète comme si: et cela me donne des résultats: p> Je suis intéressé Dans les lignes de ce résultat défini dans lesquelles la valeur est identique à celle de la rangée précédente ou suivante, comme la rangée B qui a une valeur = 2 la même chose que la rangée a. Je m'en fiche des rangées comme la rangée C qui a une valeur = 2 mais ne vient pas directement après une ligne avec valeur = 2. Comment puis-je interroger la table pour me donner toutes les lignes comme A et B seulement? Ceci est sur Oracle, si cela compte. P> p>
3 Réponses :
Utilisez les fonctions analytiques de plomb et de lag.
create table t3 (d number, v number); insert into t3(d, v) values(1, 1); insert into t3(d, v) values(2, 2); insert into t3(d, v) values(3, 2); insert into t3(d, v) values(4, 3); insert into t3(d, v) values(5, 2); insert into t3(d, v) values(6, 3); insert into t3(d, v) values(7, 4); select d, v, case when v in (prev, next) then '*' end match, prev, next from ( select d, v, lag(v, 1) over (order by d) prev, lead(v, 1) over (order by d) next from t3 ) order by d ;
Pourquoi avez-vous commander par d b> lorsque les données sont déjà commandées par D B> par vos inserts? En outre, le problème initial ne semblait pas avoir besoin de tri pour exécuter correctement.
Alors que @janek Bogucuki a souligné le plomb et le décalage est probablement le moyen le plus simple d'accomplir cela - mais juste pour le plaisir essayez de le faire en utilisant uniquement les opérations de jointure de base:
SELECT mydate, VALUE FROM (SELECT a.mydate, a.value, CASE WHEN a.value = b.value THEN '*' ELSE NULL END AS flag1, CASE WHEN a.value = c.value THEN '*' ELSE NULL END AS flag2 FROM (SELECT ROWNUM AS outer_rownum, mydate, VALUE FROM mytable ORDER BY mydate) a LEFT OUTER JOIN (select ROWNUM-1 AS inner_rownum, mydate, VALUE from mytable order by myDATE) b ON b.inner_rownum = a.outer_rownum LEFT OUTER JOIN (select ROWNUM+1 AS inner_rownum, mydate, VALUE from mytable order by myDATE) c ON c.inner_rownum = a.outer_rownum ORDER BY a.mydate) WHERE flag1 = '*' OR flag2 = '*';
ROWNUM est affecté avant le tri des résultats afin que cela ne soit pas garanti de fonctionner. Cela montre comment Row_Number () peut être utilisé à la place (pour obtenir une séquence ascendante de nombres correspondant à la commande par clause): Sélectionnez Rownum, Row_Number () sur (commander par V-D) à partir de la commande T3 par V-D; Cela utilise les données de ma réponse ci-dessus.
Ceci est une version simplifiée de la réponse de @bob Jarvis, la principale différence étant l'utilisation d'une seule sous-requête au lieu de quatre,
Y a-t-il d'autres champs dans la table, par exemple une clé primaire séquentielle? Cela faciliterait la tâche! Est-ce une table de transaction ou peut-on supprimer (c'est-à-dire des jointures et des tests avec ID-1 ou ID + 1)?
@Kieren Oui, il y a une clé primaire, mais elles sont distribuées dans un ordre incompatible avec le champ Date. Je ne sais pas ce que vous avez l'intention de "jointures et tests", mais oui, les enregistrements sont supprimés et remplacés assez souvent.