2009-09-04 5 views
2

Le problème est:Fusion de deux tables avec un champ unique commun dans MySql

Nous avons repris un site Web qui a une communauté active de membres. Nous avons reçu le vidage de l'application et de la base de données et nous avons réussi à faire fonctionner le site sur un nouveau serveur et le DNS a été changé.

Le problème est que la base de données est désynchronisée dans le temps nécessaire pour nous transférer les fichiers et le DNS. Maintenant que le DNS a changé et qu'il n'y a aucune chance que la base de données soit désynchronisée, nous avons reçu la commande members2, qui correspond à la table du serveur d'origine avec les données supplémentaires.

Les deux tableaux ressemblent à ceci Alors

`idmembers` int(10) unsigned NOT NULL auto_increment, 
`firstName` varchar(20) default NOT NULL, 
`lastName` varchar(20) default NOT NULL, 
`email` varchar(255) default NOT NULL, 
`date` varchar(10) default '0', 
`source` varchar(50) default 'signup' 
PRIMARY KEY (`idmembers`), 
UNIQUE KEY `email` (`email`) 

la première table est appelée membres1 et est la base de données en direct, ce qui manque une charge de membres de membres2. Je dois les fusionner ensemble tout en gardant les membres1 tels quels et en permettant aux courriels uniques des membres2 d'être insérés dans les membres1.

Je suppose qu'il y a du SQL pour cela, mais je n'ai aucune idée de ce que ça pourrait être. Ma seconde approche, moins préférable, serait d'utiliser un outil comme PhpMyAdmin pour exporter tous les enregistrements de membres2 après une certaine date et de les réimporter dans members1 mais le problème est qu'ils exportent tous depuis members2 avec un idmembers qui est en conflit avec members1. (comme un auto-incrément est utilisé dans les deux)

Répondre

0

Il suffit d'écrire un script de portage rapide qui sélectionne les champs qui manquent dans "members1" puis fait un INSERT pour chacun dans la table "members2".

Vous devrez peut-être vérifier si vous avez besoin d'une adresse e-mail unique, et vous pensez qu'il pourrait y avoir des doublons.

1

La suggestion la plus importante est de le faire sur une copie de votre base de données, pas la base de données en direct, jusqu'à ce que vous soyez certain que le processus aboutit à la correction de la fusion!

D'abord, vous devriez vérifier pour voir s'il y a des lignes membres2 avec des adresses e-mail en double qui existent déjà dans membres1:

SELECT members2.* 
FROM members1 JOIN members2 USING (email); 

S'il y en a (je l'espère, ce sera peu), les réparer manuellement, ou supprimez chaque ligne qui est vraiment un compte en double d'une personne qui a déjà un compte dans members1 (gardez bien sûr les données de sauvegarde).

S'il existe d'autres cas de comptes membres redondants qui doivent être considérés comme des doublons et non insérés en tant que nouveaux membres, vous devrez peut-être gérer cela manuellement. Ceci est un exemple d'un problème plus général de nettoyage de base de données ou de-duping qui ne peut généralement pas être entièrement automatisé.

Vous pouvez copier des lignes de membres2 dans membres1 tout en générant de nouvelles valeurs id comme ceci:

INSERT INTO members1 (`firstName`, `lastName`, `email`, `date`, `source`) 
    SELECT `firstName`, `lastName`, `email`, `date`, `source` 
    FROM members2; 

Oui, vous devez nommer toutes les colonnes. En omettant idmembers à partir de cette requête, cette colonne utilisera son comportement par défaut qui est de générer une nouvelle valeur d'ID.

Vous n'avez pas dit que vous aviez besoin de mettre à jour d'autres tables qui référencent ces nouveaux membres par leur identifiant.Si c'est le cas, vous devez créer une nouvelle table pour mapper l'ID members2 au nouveau nombre généré lorsque vous les importez dans members1. Vous devrez suivre le conseil de @ ijclarkson d'insérer les membres un à la fois, ainsi vous pouvez noter le nouvel identifiant généré.

SELECT * FROM members2; 

-- loop over results in a script: 

    INSERT INTO members1 (`firstName`, `lastName`, `email`, `date`, `source`) 
    VALUES (?, ?, ?, ?, ?); 

    INSERT INTO members_id_map (idmembers1, idmembers2) 
    VALUES (LAST_INSERT_ID(), ?); -- use idmembers from the query on members2 

-- end loop 
2

Si je comprends bien votre question, il y a deux questions distinctes ici:

  1. Ajout complètement nouveaux enregistrements membres de membres2 en membres1
  2. Mise à jour du champ email dans membres1, si quelqu'un l'a modifié dans membres2

en ce qui concerne le premier cas, vous devriez pouvoir faire quelque chose comme:

INSERT INTO members1 ('idmembers', 'firstname', etc.) 
SELECT 'idmembers', 'firstname', etc. 
    FROM members2 
    WHERE idmembers NOT IN (SELECT idmembers FROM members1) 

En ce qui concerne le second cas, quelque chose comme:

UPDATE members1 m1 LEFT JOIN members2 m2 
ON m1.idmembers = m2.idmembers 
SET m1.idmembers = m2.idmembers 
WHERE m2.idmembers IS NOT NULL AND m2.idmembers != m1.idmembers 

(Note 1: Les deux déclarations construites 'ad hoc' et non testés!)
(NOTE 2: Les deux déclarations supposent que la clé primaire 'de idmember' n'a pas changé lors de la migration des membres1! Si cela se produit, ces requêtes ne fonctionneront pas.)
(Note3: Si vous rencontrez le problème 'different idmember keys' de Note2, vous pouvez toujours utiliser les requêtes, mais modifiez les opérations de comparaison et de jointure pour utiliser le champ email. alors vous devrez d'abord exécuter la deuxième requête pour éviter les doublons)

Questions connexes