7
votes

Trouver des gammes continues dans un ensemble de nombres

J'ai un ensemble de numéros de téléphone raisonnablement grand (environ 2 millions) dans une table de base de données. Ces chiffres ont été insérés dans des blocs. Il existe donc de nombreuses plages continues de nombres, de 10 chiffres à 10 mille dans une plage. Certains de ces chiffres sont utilisés et sont donc marqués comme indisponibles, le reste est disponible. Compte tenu d'un numéro particulier, j'ai besoin d'un moyen de trouver des plages continues de nombres, ci-dessus et inférieur à ce nombre. La gamme devrait continuer jusqu'à ce qu'il trouve un numéro indisponible ou rencontre la limite de deux gammes.

Par exemple, étant donné l'ensemble suivant: P>

1000
1001
1002
1010
1011
1012
1013
1020
1021
1022


0 commentaires

4 Réponses :


1
votes

SQL ne peut pas vraiment faire cela dans une seule requête (sauf qu'il y a des améliorations de SQL natives, je ne sais pas), car SQL ne peut pas accéder à la ligne "avant" ou "après".

Vous avez besoin Pour passer à travers la séquence dans une boucle.

Vous pouvez essayer NHibernates énumérable , qui ne chargait pas les entités en mémoire, mais ne crée que des proxies. En fait, je ne pense pas que c'est une bonne idée, car il créera des mandataires pour l'ensemble de 2 millions de chiffres.

plan B, utilisation de la pagination. À peu près, il ressemble à ceci: xxx

et le même pour la plage avant dans l'autre sens.


7 commentaires

La condition doit être où pn.number> =: entrée n'est-ce pas?


SQL a stocké des procédures stockées et, surtout, il prend également en charge les requêtes récursives ( en.wikipedia.org/wiki/hierarchical_query " a>).


@ PÉTER: Pourquoi? Pour voir si le numéro d'entrée existe? Peut-être que ces détails sont hors de portée de ma réponse.


@UnReason: Pourquoi écrire des procédures stockées si vous pouvez l'écrire en C #? Si la performance ne vous oblige pas à utiliser un SP, je l'éviterais. Et si je dis "force", je veux dire "force". Pas l'opinion générale que pourrait un problème et SP devrait être utilisé juste pour être en sécurité. Les SP sont trop chers pour les projets basés sur des langages de programmation de haut niveau.


@Stefan, désolé mon commentaire était en réponse à votre affirmation que SQL ne peut pas faire prev / Suivant et ajouter qu'elle peut également faire une récursive. En ce qui concerne les procédures stockées et le code côté client - les raisons des procédures stockées peuvent être multiples - de la sécurité, à l'abstraction, de nettoyer la séparation de l'application VS Server Fonctionnalité, à la performance; Mais je ne faisais pas de commentaire à ce sujet, comme la décision de plus haut niveau / architectural (faire certaines choses sur le côté client peut réellement aider la performance, même si ce n'est pas un de ceux-ci). Tout ce que je voulais dire, c'est que SQL peut vraiment le faire. :)


@UnReason: OK, je comprends et je suis d'accord. Je distingue les requêtes SQL et SQL de procédure. Je la rephère pour l'exprimer.


Oracle en fait le plomb et la décalage pour vérifier les lignes précédentes et suivantes.



0
votes

2 commentaires

Et si la récursion maximale pouvait réellement être de 2 millions? Où obtenez-vous le lien vers le numéro précédent?


En ce qui concerne la taille, OP dit qu'il devrait être jusqu'à 10k, que je pense que MS SQL soutiendrait (je note la possibilité de casser des choses dans la réponse). Je n'ai pas votre question concernant le nombre précédent - entre l'ancre et la requête récursive, je ne vois pas de problème à rejoindre.



18
votes

théoriquement Les éléments d'un ensemble n'ont aucune valeur particulière, je suppose donc que vous avez également une colonne d'identification continue qui définit l'ordre des chiffres. Quelque chose comme ceci: xxx

Vous pouvez créer une colonne supplémentaire contenant le résultat de numéro d'identifiant : xxx < p> Les nombres dans la même gamme auront le même résultat dans la colonne DIFF.


7 commentaires

Pensait dans ces lignes quelque part, mais ne l'a pas vu +1


Ceci est intelligent mais ne répond pas totalement à la question. Si l'une des lignes est supprimée, l'identifiant n'est pas recalculé, vous avez donc un ensemble non continu avec le même diff pour toutes les valeurs. Je pourrais peut-être utiliser un numéro de rangée généré dans le cadre d'une requête pour accélérer les choses.


Oui, vous pouvez utiliser la fonction Row_Number () sur la colonne ID pour générer une séquence continue pour le calcul DIFF. msdn.microsoft.com/en-us/library/ms186734.aspx


Si intelligent, élégant, avec la fonction Row_Number, il devient parfait, +10


Une pensée aléatoire: cela pourrait également être considéré comme un exemple d'ANL (ou de l'outil) pour transformer des données séquentielles à des données relationnelles (création d'un attribut relationnel, d'informations relatives à des informations séquentielles, pour une propriété particulière).


C'est rarement un problème dans le monde réel, mais vous ne devriez pas compter sur la colonne d'identité de la commande.


Une idée brillante, merci beaucoup, utilisée ici ici Stackoverflow.com/a/17954275/1744834



0
votes

Utilisez une table auxiliaire de toutes les valeurs séquentielles possibles ou de matérialiser un dans un E.G. xxx


0 commentaires