J'ai une table contenant les données ci-dessous.
Disons que j'ai deux versions du projet et que j'ai besoin de migrer les données d'une ancienne version vers une nouvelle version.
Disons tblFolders
en version1
SELECT id, foldername, b.version2userid AS createdby, b.version2userid AS modifiedby FROM tblfolders A WITH(nolock) LEFT JOIN tblusersmapping B WITH(nolock) ON a.createdby = b.version1userid, a.modifiedby = b.version1userid
Et une autre table ayant l'ID utilisateur des deux versions.
Disons son tblUsersMapping
p>
SELECT id, foldername, B.version2userid AS CreatedBy FROM tblfolders A WITH(nolock) LEFT JOIN tblusersmapping B WITH(nolock) ON A.createdby = B.version1userid
Je dois maintenant transférer des données de la version 1 à la version 2. Lorsque je transfère des données, les identifiants Créé par et Modifié par doivent par de la nouvelle version.
Donc, même si j'ai des données comme ci-dessous
| 1 | SIMPLE | 321 | 21 |
Il devrait être transféré comme ci-dessous
| 1 | SIMPLE | 5 | 6 |
6 Réponses :
Si vous souhaitez remplir à la fois la colonne à laquelle chaque colonne se joint à une ligne différente, dans ce cas, vous devez joindre la même table deux fois comme suit. Vous ne pouvez pas l'obtenir avec une seule table jointe comme vous le souhaitez.
SELECT id, foldername, B.version2userid AS CreatedBy C.Version2UserID AS ModifiedBy FROM tblfolders A WITH(nolock) LEFT JOIN tblusersmapping B WITH(nolock) ON A.createdby = B.version1userid LEFT JOIN tblusersmapping C WITH(nolock) ON A.ModifiedBy = C.version1userid
Merci pour votre réponse. Avez-vous une autre solution dont je n'ai pas besoin et une autre jointure? Parce que comme mentionné dans la question, il peut y avoir plus de données de crore dans le tableau et une seule jointure est déjà un gros problème pour moi.
Dans votre scénario actuel, vous devez l'utiliser deux fois et c'est très courant. Si vos tables sont correctement indexées, vous ne devriez pas avoir de problèmes de performances.
Vous pouvez utiliser la sélection multiple qui peut vous aider.
SELECT id, foldername, (SELECT version2userid from tblUsersMapping where Version1UserID=tblfolders.CreatedBy) AS CreatedBy, (SELECT version2userid from tblUsersMapping where Version1UserID=tblfolders.ModifiedBy) AS ModifiedBy FROM tblfolders
C'est une mauvaise idée car elle ralentira lorsque la table aura de nombreux enregistrements.
Oui, vous avez raison, en termes de performances, cela ralentira un peu.
Essayez ceci, cela fonctionnera sur tous les exemples de données,
select tf.id,tf.FolderName ,oa.Version2UserID as CreatedBy ,oa1.Version2UserID as ModifiedBy from @tblFolders tf outer apply(select top 1 Version2UserID from @tblUsersMapping tu where tu.Version1UserID= tf.CreatedBy order by id desc)oa outer apply(select top 1 Version2UserID from @tblUsersMapping tu where tu.Version1UserID= tf.ModifiedBy order by id desc)oa1
Vous pouvez utiliser UDF
pour renvoyer modifiedby
et INNER JOIN
au lieu de LEFT JOIN
(si l'exigence est remplie) comme ci-dessous. Je pense que cela aidera dans la préformance
id foldername createdby modifiedby 1 SIMPLE 321 21 2 SIMPLE1 884 500
OUTPUT:
CREATE TABLE tblFolders (id INT, folderName VARCHAR(20), createdBy INT, modifiedBy INT) INSERT INTO tblFolders VALUES (1,'SIMPLE', 5,6), (2,'SIMPLE1', 8,1) CREATE TABLE tblUsersMapping(id INT, Version1UserID INT, Version2UserID INT) INSERT INTO tblUsersMapping VALUES (1,1,500), (2,2,465), (3,3,12), (4,4,85), (5,5,321), (6,6,21), (7,7,44), (8,8,884) SELECT a.id, a.foldername, b.version2userid AS createdby, dbo.FNAReturnModifiedBy(a.modifiedBy) AS modifiedby FROM tblfolders A WITH(nolock) INNER JOIN tblusersmapping B WITH(nolock) ON a.createdby = b.version1userid --Function IF OBJECT_ID(N'dbo.FNAReturnModifiedBy', N'FN') IS NOT NULL DROP FUNCTION dbo.FNAReturnModifiedBy GO CREATE FUNCTION dbo.FNAReturnModifiedBy(@updated_by INT) RETURNS INT AS BEGIN DECLARE @updateUserID INT SELECT @updateUserID = Version2UserID FROM tblusersmapping WHERE Version1UserID = @updated_by RETURN @updateUserID END
Cela donne un résultat vraiment plus rapide. Il y a quelques incohérences dans le décompte par rapport à la jointure gauche, je vais donc vérifier cela et je dois également vérifier comment adapter cette requête dans mon code car j'ai tout le système dynamique et les requêtes sont créées de manière dynamique en fonction de la structure de la classe. Merci d'avoir répondu.
Remarque:
Je ne savais pas comment trouver les performances des requêtes. J'ai écrit uniquement pour votre sortie attendue.
J'utilise SQL Server 2012.
Je n'ai pas utilisé plus d'une jointure.
La requête a effectué JOIN, GROUP BY, ROW_NUMBER (), CASE
au lieu de deux LEFT JOIN
Entrée:
id FolderName Version1UserID Version2UserID 1 SIMPLE 321 21 2 SIMPLE1 884 500 3 File 44 321
Requête:
select id, FolderName , max (case when rn = 1 then Version2UserID end) Version1UserID , max (case when rn = 2 then Version2UserID end) Version2UserID from ( select v.id, v.FolderName, u.Version1UserID, u.Version2UserID , ROW_NUMBER () over (partition by v.id order by v.id, v.CreatedBy, case when v.CreatedBy > v.ModifiedBy then u.Version1UserID end desc ) rn , v.CreatedBy, v.ModifiedBy from ##ver v join ##veruser u on u.Version1UserID in (v.CreatedBy, v.ModifiedBy) ) a group by id, FolderName order by id
Essayez celui-ci.
Select a.id,folderName,b.Version2UserId as createdby,c.Version2UserId as modifiedby from tblFolders as a WITH(nolock) inner join tblUsersMapping as b WITH(nolock) on a.createdby =b .Version1UserID inner join tblUsersMapping as c WITH(nolock) on a.modifiedBy =c .Version1UserID