Existe-t-il un moyen de calculer une requête où une ligne dans une nouvelle colonne prend la prochaine valeur qui est supérieure à elle-même dans une colonne différente. J'ai essayé d'utiliser une méthode de rolling max, mais je me suis heurté à un mur car cela implique de spécifier un nombre spécifique de lignes à comparer comme ceci :
select t.*,
max(val) over (order by date rows between 2 preceding and current row) max3
from t;
Où nous devons spécifier que le maximum sera calculé entre la ligne actuelle et 2 lignes précédentes.
Cependant, ce que je voudrais faire est quelque chose comme ceci :
---------------------------------------
val | id | newcol |
2 | ABC | 4 |
2 | ABC | 4 |
2 | ABC | 4 |
4 | ABC | 10 |
4 | ABC | 10 |
10 | ABC | 9999 |
10 | ABC | 9999 |
3 | EFG | 5 |
5 | EFG | 9 |
9 | EFG | 9999 |
2 | HIJ | 9999 |
7 | KLM | 11 |
11 | KLM | 12 |
12 | KLM | 9999 |
Où je partitionne par l'id et la nouvelle col est assignée à la prochaine valeur dans la col val qui est supérieure à sa propre valeur (indépendamment du nombre de lignes en avant) et assigne un grand nombre arbitraire (9999) si c'est déjà la valeur la plus élevée dans sa partition.
Jusqu'à présent, j'ai trouvé ceci :
SELECT val,
id,
CASE WHEN val = MAX(val) OVER(PARTITION BY id) THEN 9999
ELSE MAX(val) OVER(partition by id ORDER BY val ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
END AS newcol
FROM table
ORDER BY ID;
Cependant, cela ne fait qu'attribuer la valeur maximale de la partition à toute valeur qui n'est pas le maximum, comme ceci :
---------------------------------------
val | id | newcol |
2 | ABC | 10 |
2 | ABC | 10 |
2 | ABC | 10 |
4 | ABC | 10 |
4 | ABC | 10 |
10 | ABC | 9999 |
10 | ABC | 9999 |
3 | EFG | 9 |
5 | EFG | 9 |
9 | EFG | 9999 |
2 | HIJ | 9999 |
7 | KLM | 11 |
11 | KLM | 11 |
12 | KLM | 9999 |
Toute aide serait très appréciée.