2 votes

Divisez les intervalles de nombres en groupes

J'ai la séquence de nombres ci-dessous et je veux créer un nouveau groupe de nombres chaque fois que le nombre suivant présente une différence de plus d'une unité par rapport à la valeur précédente, c'est-à-dire en rompant l'intervalle continu

Tableau T

value
1 
2
3
5
6
7
15
16
17
18

Groupes à former d'intervalle continu :

min max
1   3
5   7
15  18

J'essaie de numéroter les lignes en utilisant la fonction dense_rank(), comme dans l'exemple ci-dessous, puis je pourrai regrouper par rankNumber et obtenir les valeurs MIN(value) et MAX(value), mais je ne trouve pas de modèle à utiliser dans la clause PARTITION BY de cette fonction.

value rankNumber
1     1
2     1
3     1
5     2
6     2
7     2
15    3
16    3
17    3
18    3

    WITH T2 AS
    (
     SELECT value, LEAD(value) OVER(ORDER BY value) as nextValue
     FROM T 
    )

    SELECT value, DENSE_RANK() 
     OVER(PARTITION BY CASE WHEN nextValue - value > 1 THEN 1 ELSE 0 END ORDER BY value)
    FROM T2

Code pour créer la table :

CREATE TABLE t(
    value   INT
);
INSERT INTO t VALUES
    (1), (2), (3), (5), (6), (7), (15), (16), (17), (18);

Sortie actuelle en utilisant la requête ci-dessus :

value rankNumber
1     1
2     2
3     1
5     3
6     4
7     2
15    5
16    6
17    7
18    8

4voto

King King Points 30608

Vous devez trouver un moyen de transformer les séquences en groupes correspondants. Je viens d'apprendre cette astuce par un autre utilisateur ici même. En utilisant le ROW_NUMBER qui passe par tous les enregistrements, vous pouvez calculer la clé de groupe en soustrayant le value sur le même enregistrement à partir de ce numéro de ligne. Si le values sont consécutives, il n'y aurait pas de changement dans le résultat de la soustraction (donc la même clé de groupe produite). Dans le cas contraire, la clé de groupe passe à la valeur suivante (inférieure). À chaque saut, la clé de groupe sera plus petite.

Voici la requête :

select min(value) min, max(value) max
from (select value, ROW_NUMBER() over (order by value) - value as [key] 
      from t) v
group by [key]
order by min

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X