2010-06-07 5 views
0

J'essaie de résoudre un problème dont j'ai hérité avec un mauvais traitement de différentes sources de données. J'ai une table d'utilisateur qui contient les deux bons et mauvais utilisateurs.INSERT..ON DUPLICATE KEY UPDATE - mais pas en utilisant la clé en double pour comparer

create table `users`( 
    `user_id` int(13) NOT NULL AUTO_INCREMENT , 
    `email` varchar(255) , 
    `name` varchar(255) , 
    PRIMARY KEY (`user_id`) 
); 

Dans ce tableau, la clé primaire est actuellement définie comme user_id.

J'ai une autre table ('users_evil') qui contient UNIQUEMENT les mauvais utilisateurs (tous les utilisateurs de cette table sont inclus dans la première table) - les ID utilisateur sur cette table ne correspondent PAS à ceux de la première table.

Je veux avoir tous mes utilisateurs dans une table, et simplement signaler les bons et les mauvais. Qu'est-ce que je veux faire est de modifier la table des utilisateurs et ajouter une colonne ('mal') par défaut 0. Je veux ensuite vider les données de ma table 'users_evil'), puis exécutez un INSERT..ON DUPLICATE KEY UPDATE avec ces données dans la première table (réglage 'evil' = 1 où les emails correspondent)

Le problème est que le 'PK' est défini sur l'ID utilisateur et non sur le 'email'. Toutes les suggestions, ou même une autre stratégie pour réussir cela. Puis-je exécuter cette instruction mais traiter une autre colonne comme PK uniquement pour la durée de l'instruction?

Répondre

2
ALTER table add column... 

UPDATE users set evil = 0; 

UPDATE users u join users_evil ue ON ue.email = u.email and u.name = ue.name set evil = 1;  

il vous suffit de mettre à jour les mauvais utilisateurs utilisateurs Table

+0

Je n'étais pas au courant que vous pourriez vous joindre à une mise à jour - c'est exactement pourquoi je poste à SO. Merci pour cette réponse. – calumbrodie

+0

Je ne vois pas l'intérêt d'avoir des index temporaires pour une telle requête si vous ne l'exécutez qu'une seule fois. –

+0

En effet. Votre méthode a beaucoup plus de sens. Marqué comme correct, merci pour votre aide – calumbrodie

2

Qu'en est-ce:

update users set evil=1 where email in (select email from users_evil); 
+0

Cela devrait fonctionner mais il semble que mon serveur plante et brûler. Je remarque que vous ne pouvez pas faire une mise à jour EXPLAIN dans mysql? Mes ensembles de données ne sont pas massifs (environ 20k lignes). Merci – calumbrodie

0

Vous pouvez effectuer une jointure externe des tables, puis détecter où un utilisateur est mal en recherchant des valeurs non NULL:

UPDATE (users LEFT OUTER JOIN evil_users ON users.email = evil_users.email) 
    SET users.evil=1 
    WHERE evil_users.some_field IS NOT NULL; 
+1

En fait, maintenant que je pense à ce sujet, la jointure externe n'est même pas nécessaire. Voir la réponse d'Imre L pour une version sans la jointure externe. – VeeArr

+0

Merci pour votre réponse – calumbrodie

Questions connexes