9
votes

Comment faire à l'opposé de "Row_Number () sur (partition par [COL] commander par [COL])"

J'essaie de combiner des entrées en double dans une table de données et de leur donner un nouveau numéro.

Voici un exemple de jeu de données ( copie annulable ) p> xxx pré> > En ce moment, cela me donne les résultats p> xxx pré>

Cependant, c'est l'opposé de ce que je veux, le newidnum code> réinitialise son compteur de temps qu'il trouve un nouvelle combinaison de la clé. Je veux que toute la même combinaison ait le même identifiant. Donc, si c'était le comportement de la façon dont je voulais avoir les résultats suivants p> xxx pré>

Quelle est la bonne façon d'obtenir les résultats que je veux? P>


je n'ai pas inclus cette exigence dans le message original fort>: j'ai besoin du newidnum code> pour produire les mêmes numéros sur les exécutions ultérieures de cette requête pour les lignes existantes si plus de lignes obtiennent Ajouté (en supposant que toutes les nouvelles lignes auront une "valeur" plus élevée "une valeur" si une commande par commande est effectuée sur la colonne ID) p>

Donc, si si à une dernière date, ce qui suit a été effectué P>

NewIDNum             ID   First Last  Phone         NonKeyField
-------------------- ---- ----- ----- ------------- -----------
1                    A    John  Smith (555)555-1234 ASDF
1                    B    John  Smith (555)555-1234 GHJK
2                    C    Jane  Smith (555)555-1234 QWER
1                    D    John  Smith (555)555-1234 RTYU
3                    E    Bill  Blake (555)555-0000 BVNM
3                    F    Bill  Blake (555)555-0000 %^&*
1                    G    John  Smith (555)555-1234 !#RF
1                    H    John  Smith (555)555-1234 4321
4                    I    Jake  Jons  (555)555-1234 1234
1                    J    John  Smith (555)555-1234 2345


0 commentaires

4 Réponses :


8
votes

Vous pouvez utiliser dense_rank () code>: xxx pré>

En réponse à votre commentaire, vous pouvez trier au minimum de l'ancien ID code > Colonne par groupe de lignes avec le même (premier, dernier, téléphone) code> Combinaison: P>

select  *
from    (
        select  dense_rank() over (order by min_id) as new_id
        ,       *
        from    (
                select  min(id) over (
                            partition by First, Last, Phone) as min_id
                ,       *
                from    @tmpTable 
                ) as sub1
        ) as sub3
order by
        new_id


6 commentaires

Puis-je l'obtenir pour être commandé par l'ancien identifiant? J'ai besoin des nouveaux identifiants pour produire les mêmes numéros pour les lignes existantes si plus de lignes sont ajoutées (en supposant que de nouvelles lignes auront une "valeur" plus élevée "si une commande par est effectuée sur la colonne ID)


Pour votre mise à jour: l'ajout du test "Jake Jons" le fait que le Dr des 2 et John et Jane Smith, les deux changent de 1.


Mis à jour pour attribuer un rang dense basé sur le plus bas ID par (premier, dernier, téléphone) groupe.


J'ai compris Ma propre méthode à l'aide de groupe par, mais en exécutant votre requête et la mine à côté de l'autre, la vôtre est plus rapide par exécution temps %. Merci pour l'aide!


Est sous-3 Nessasary? pourquoi ne pas mettre la commande finale à l'intérieur de Sub3 et retirer la couche la plus externe (je ne vais même pas utiliser la commande par ma requête réelle (il alimente un insérer dans ), mais je suis curieuse).


Sub3 empêche la répétition de la définition de new_id . Si vous n'avez pas besoin de la commande, vous pouvez certainement l'omettre. Comme vous pouviez voir avec un test simple :)



-1
votes

Cela devrait fonctionner

select dense_rank() over (order by First, Last, Phone) NewIDNum, *  
from @tmpTable order by ID


1 commentaires

Voir mon commentaire à la réponse de Andomar.



1
votes

Bâtiment sur la réponse originale de @ Andomar - Cela fonctionnera sur vos exigences mises à jour (bien que cela ne soit probablement pas bien à l'échelle)

select
    DENSE_RANK() over (ORDER BY IdRank, First, Last, Phone) AS NewIDNum,
    ID,
    First,
    Last,
    Phone,
    NonKeyField
from
(
    select
        MIN(ID) OVER (PARTITION BY First, Last, Phone) as IdRank,
        *
    from
        @tmpTable
) as x
order by
    ID;


0 commentaires

0
votes

Merci à Réponse de Andomar en tant que point de saut que je suis résolu moi-même xxx pré>

Ceci produit P>

rn                   ID   First Last  Phone         NonKeyField
-------------------- ---- ----- ----- ------------- -----------
1                    A    John  Smith (555)555-1234 ASDF
1                    B    John  Smith (555)555-1234 GHJK
1                    D    John  Smith (555)555-1234 RTYU
1                    G    John  Smith (555)555-1234 !#RF
1                    H    John  Smith (555)555-1234 4321
1                    J    John  Smith (555)555-1234 2345
2                    C    Jane  Smith (555)555-1234 QWER
3                    E    Bill  Blake (555)555-0000 BVNM
3                    F    Bill  Blake (555)555-0000 %^&*
4                    I    Jake  Jons  (555)555-1234 1234


2 commentaires

Vous interrogez votre variable de table deux fois moins optimale que la solution de @ Andomar.


Cela explique mon temps d'exécution plus lent. Merci pour l'aperçu.