J'ai environ un milliard de lignes de données dans une table avec un nom et un entier compris entre 1 et 288. Pour un nom donné , chaque int est unique, et non tout entier possible dans la plage est présente - donc il y a des lacunes.
Cette requête génère un exemple de cas:
--what I have:
SELECT *
FROM ( VALUES ('foo', 2),
('foo', 3),
('foo', 4),
('foo', 10),
('foo', 11),
('foo', 13),
('bar', 1),
('bar', 2),
('bar', 3)
) AS baz ("name", "int")
Je voudrais générer une table de recherche avec une ligne pour chaque nom et séquence d'entiers contigus. Chacune de ces lignes contiendrait:
nom - la valeur du début de la colonne de nom - le premier entier de la fin de séquence contiguë - la valeur finale dans la plage de séquence contiguë -
fin - début + 1
Cette requête génère un exemple de sortie pour l'exemple ci-dessus:
--what I need:
SELECT *
FROM ( VALUES ('foo', 2, 4, 3),
('foo', 10, 11, 2),
('foo', 13, 13, 1),
('bar', 1, 3, 3)
) AS contiguous_ranges ("name", "start", "end", span)
Parce que j'ai tellement de lignes, plus efficace c'est mieux. Cela dit, je ne dois exécuter cette requête qu'une seule fois, ce n'est donc pas une exigence absolue.
Merci d'avance!
Éditer:
Je dois ajouter que les solutions PL / pgSQL sont les bienvenues (veuillez expliquer toutes les astuces - je suis encore nouveau sur PL / pgSQL).