2009-03-19 11 views
38

J'ai une table complète de données de suivi des cours spécifiques comme, le nombre de cours 6.Copier des données d'une ligne existante vers une autre ligne existante dans SQL?

Maintenant, j'ai ajouté de nouvelles données de suivi pour le numéro de cours 11.

Chaque ligne de données est pour un utilisateur pour un cours , donc pour les utilisateurs affectés à la fois au cours 6 et au cours 11, il y a deux lignes de données. Le client veut que tous les utilisateurs qui ont suivi le cours numéro 6 à tout moment après le 1er août 2008 aient aussi une note de fin pour le cours 11. Cependant, je ne peux pas simplement convertir les 6 à 11 parce qu'ils veulent conserver leurs anciennes données. cours 6.

Donc, pour chaque ligne qui a un numéro de cours de 6, est marqué comme complet, et est supérieur à la date du 1er août 2008, je veux écrire les données d'achèvement sur la ligne qui contient le suivi pour le cours 11 pour cet utilisateur spécifique.

Je devrai reporter les données du cours 6 rangs au rang 11 afin que les choses comme le score de l'utilisateur et la date d'achèvement soient déplacées.

Voici la structure de la table:

userID (int) 
courseID (int) 
course (bit) 
bookmark (varchar(100)) 
course_date (datetime) 
posttest (bit) 
post_attempts (int) 
post_score (float) 
post_date (datetime) 
complete (bit) 
complete_date (datetime) 
exempted (bit) 
exempted_date (datetime) 
exempted_reason (int) 
emailSent (bit) 

Certaines valeurs seront NULL et noms d'utilisateur/courseID évidemment ne seront pas reportés comme cela est déjà au bon endroit.

Répondre

60

Peut-être que je lis le faux problème, mais je crois que vous avez déjà inséré le cours 11 dossiers et ont simplement besoin de mettre à jour ceux qui répondent aux critères que vous avez énumérés avec les données de 6 cours.

Si tel est le cas, vous aurez envie d'utiliser un UPDATE ... FROM déclaration:

UPDATE MyTable 
SET 
    complete = 1, 
    complete_date = newdata.complete_date, 
    post_score = newdata.post_score 
FROM 
    (
    SELECT 
     userID, 
     complete_date, 
     post_score 
    FROM MyTable 
    WHERE 
     courseID = 6 
     AND complete = 1 
     AND complete_date > '8/1/2008' 
    ) newdata 
WHERE 
    CourseID = 11 
    AND userID = newdata.userID 

See this related SO question for more info

+1

toute chance que vous pourriez m'expliquer comment fonctionne cette chose newdata, qui ressemble à une chose pratique mais je ne suis pas tout à fait sûr que je l'obtiens – BigOmega

+0

cela a fonctionné, merci! – BigOmega

+0

@Ryan l'avez-vous exécuté/vérifié? – eglasius

4

Use SELECT to Insert records

INSERT tracking (userID, courseID, course, bookmark, course_date, posttest, post_attempts, post_score, post_date, complete, complete_date, exempted, exempted_date, exempted_reason, emailSent) 
SELECT userID, 11, course, bookmark, course_date, posttest, post_attempts, post_score, post_date, complete, complete_date, exempted, exempted_date, exempted_reason, emailSent 
FROM tracking WHERE courseID = 6 AND course_date > '08-01-2008' 
+0

hmm OK, mais pourrai-je faire une WHERE qui vérifie les commandes INSERT et SELECT étant que ce soit dans la même table? – BigOmega

+0

Devrait pouvoir, donner l'exemple que je viens d'ajouter un essai. –

+0

Il est probable que vous deviez définir complete_date à la date actuelle, si c'est une exigence. Cela devrait vous aider à démarrer, cependant. –

10
UPDATE c11 
SET 
    c11.completed= c6.completed, 
    c11.complete_date = c6.complete_date, 
-- rest of columns to be copied 
FROM courses c11 inner join courses c6 on 
    c11.userID = c6.userID 
    and c11.courseID = 11 and c6.courseID = 6 
    -- and any other checks 

J'ai toujours vu la clause From d'une mise à jour, comme l'un d'une sélection normale. En fait, si vous voulez vérifier ce qui sera mis à jour avant d'exécuter la mise à jour, vous pouvez remplacer les parties de mise à jour par un select c11. *. Voir mes commentaires sur la réponse du canard boiteux.

10

Copie une valeur d'une ligne à toutes les autres lignes qualifiées dans la même table (ou tables différentes):

UPDATE `your_table` t1, `your_table` t2 
SET t1.your_field = t2.your_field 
WHERE t1.other_field = some_condition 
AND t1.another_field = another_condition 
AND t2.source_id = 'explicit_value' 

Commencez par aliasing la table en 2 références uniques de sorte que le serveur SQL peut dire les séparer

Ensuite, spécifiez le (s) champ (s) à copier.

dernier, préciser les conditions de sélection des lignes

En fonction des conditions dans lesquelles vous pouvez copier à partir d'une seule ligne à une série, ou vous pouvez copier une série à une série. Vous pouvez également spécifier des tables différentes et vous pouvez même utiliser des sous-sélections ou des jointures pour autoriser l'utilisation d'autres tables pour contrôler les relations.

+3

Merci, beaucoup plus clair que la réponse acceptée :) – Metal450

+3

Il ne fonctionne pas dans Microsoft SQL Server. Message d'erreur: Syntaxe incorrecte près de 't1'. – palota

+0

Je suis d'accord avec @ Metal450 - beaucoup plus clair. –

-1

Cela fonctionne bien pour gérer des enregistrements entiers.

UPDATE your_table 
SET new_field = sourse_field 
+0

cela copie des colonnes, pas des lignes – yzorg

1

Essayez ceci:

UPDATE barang 
SET ID FROM(SELECT tblkatalog.tblkatalog_id FROM tblkatalog 
WHERE tblkatalog.tblkatalog_nomor = barang.NO_CAT) WHERE barang.NO_CAT <>''; 
-2
UPDATE MyTable 
SET 
    complete = 1, 
    complete_date = newdata.complete_date, 
    post_score = newdata.post_score 
FROM 
    (
    SELECT 
     userID, 
     complete_date, 
     post_score 
    FROM MyTable 
    WHERE 
     courseID = 6 
     AND complete = 1 
     AND complete_date > '8/1/2008' 
    ) 
+0

s'il vous plaît fournir quelques explications et éditez aussi votre message pour avoir la bonne mise en forme – Pooya

+0

où est "newdata" déclaré? – Petar