-1
votes

Attribuez la même clé pour les enregistrements en double pour l'identification dans SQL

Dans mes données client, il existe des enregistrements en double basés sur plusieurs champs clés tels que la même adresse électronique, le téléphone ou l'adresse postale de différents enregistrements. Je souhaite identifier des ensembles d'enregistrements en double en fonction de la répétition de courrier électronique, de téléphone ou d'une adresse postale et d'attribuer leur numéro de répétition (idem id) pour les marquer en tant que clients répétitifs. Après cela, je veux déplacer des enregistrements de clients uniques à une autre table qui n'aura aucun doublage et servir de table d'enregistrement maître.

Je suis capable d'utiliser dense_rank pour classer les enregistrements dupliqués avec le même numéro mais Vous êtes coincé ensuite, je ne sais pas comment attribuer de nouvelles clés à NewCustid pour tous les enregistrements. p>

Tables initiales et données d'échantillons P>

RN  |FirstName  |LastName   |Email
1   |Ahmad      |Raza       |ahmaddba@gmail.com
2   |Hamid      |Alvi       |hamidalvi@gmail.com
2   |Hamid      |Alvi       |hamidalvi@gmail.com
2   |Hamid      |Alvi       |hamidalvi@gmail.com
2   |Hamid      |Alvi       |hamidalvi@gmail.com
2   |Hamid      |Alvi       |hamidalvi@gmail.com
3   |Iftikhan   |Khan       |iffikhan@gmail.com
3   |Iftikhan   |Khan       |iffikhan@gmail.com
4   |Mohsin     |Khan       |mohsinkaz@gmail.com
4   |Mohsin     |Khan       |mohsinkaz@gmail.com


0 commentaires

4 Réponses :


0
votes
WITH customers AS (
  SELECT 
    Dense_rank() OVER(
      ORDER BY 
        c.firstname, 
        c.lastname, 
        c.email
    ) AS rn, 
    * 
  FROM 
    #cust_init AS c) 
  INSERT INTO #mergedcust 
  SELECT 
    c.rn AS newcustid, 
    -1 AS DW_CustID, 
    c.firstname, 
    c.lastname, 
    c.email, 
    c.mailaddress, 
    c.phone 
  FROM 
    customers AS c 
  GROUP BY 
    c.rn, 
    c.firstname, 
    c.lastname, 
    c.email, 
    c.mailaddress, 
    c.phone;
SELECT 
  * 
FROM 
  #mergedcust

3 commentaires

Votre réponse est partiellement correcte pour la phase 2 où je souhaite déplacer des enregistrements uniques à la table fusionnée, mais manque de DW_Custid à partir de la table source Cust_init. Je pense que vous avez manqué la phase 1 où j'ai besoin de mettre à jour NewCustid dans la table source Cust_init.


Je répondais à une partie de votre question initiale que vous avez supprimée.


Je n'ai jamais supprimé rien de plus à jour la question pendant que je posais. Ce n'est peut-être pas vraiment clair mais la mise à jour des clés était toujours la première partie. Quoi qu'il en soit, j'apprécie votre réponse rapide.



0
votes

Essayez ceci-

SELECT 
ROW_NUMBER() OVER (ORDER BY A.min_cust_id) NewCustID,
B.DW_CustID,
B.FirstName,
B.LastName,
B.Email,
B.MailAddress,
B.Phone
FROM 
(
    SELECT email, MIN(dw_custID) min_cust_id
    FROM cust_init
    GROUP BY EMAIL
)A
INNER JOIN cust_init B ON A.min_cust_id = B.DW_CustID


2 commentaires

Cela ne servent pas l'objectif, il renvoie simplement le jeu de résultats en fonction de la commande par courrier électronique et implique des jointures inutiles. J'ai montré mon effort qui retourne le même résultat en utilisant CTE et dense_rank .


@Faridm S'il vous plaît vérifier à nouveau le script. J'ai mis à jour le script.



0
votes

Ceci donne le résultat souhaité que vous avez posté ci-dessus. Il suffit d'utiliser Row_Number pour numéroter vos doublons, puis prenez le premier.

UPDATE #Cust_init set NewCustID =  DR
       FROM #Cust_init t1
       INNER JOIN (SELECT dw_custid, DENSE_RANK () OVER(order by firstname,lastname,email) DR from #Cust_init) t2
       on t1.DW_CustID = t2.DW_CustID


1 commentaires

Cela revient simplement une ligne avec DW_Custid = 11 au lieu des 4 lignes requises. En outre, vous avez manqué la première partie où les nouvelles clés doivent d'abord être attribuées à NewCustid, puis à insérer des enregistrements uniques dans le tableau fusivedcust .



1
votes

Il s'agit d'un problème difficile et informellement coûtalisé, car il implique de marcher sur trois types de bords différents (adresses électroniques, téléphones et adresses de courrier).

Pour approcher cela avec une seule requête, vous pouvez utiliser récursif CTES. Malheureusement, SQL Server ne prend pas en charge les tableaux, ce qui évite ainsi que les cycles nécessitent de garder une trace des identifiants précédents que vous avez touchés, ce qui correspond à de nombreuses opérations de chaîne. P>

Voici la requête: p>

with cte ( . . . )
update t2
    set newCustId = x.newCustId
    from (select dw_custid, min(other_ci), dense_rank() over (order by min(other_ci)) as newCustId
          from cte
          group by dw_custid
         ) x join
         table2 t2
         on t2.dw_custid = x.dw_custid;


2 commentaires

Merci beaucoup pour votre gentille réponse Gordon. Il n'y a pas de restriction de la manipulation de ce cas dans une seule requête, il peut y avoir plusieurs requêtes pour résoudre ce problème et probablement, je vais les combiner dans une procédure stockée.


Gordon, pouvez-vous ajouter un autre exemple d'attribution de NewCustid à la table existante à l'aide des relevés de mise à jour? Aucune restriction à faire dans une seule requête, plusieurs requêtes préfèrent être meilleures et plus faciles à gérer.