95 votes

Mise à jour d'une requête à l'aide d'une sous-requête dans Sql Server

J'ai une structure de tableau simple comme celle-ci :

Tableau tempData

   NAME    MARKS 

 Narendra     80 
 Ravi         85 
 Sanjay       90 

Et j'ai aussi un autre nom de table comme tempDataView comme ceci

   NAME    MARKS 

 Narendra        
 Narendra        
 Narendra        
 Narendra        
 Ravi            
 Ravi            
 Sanjay          

Je veux mettre à jour la table tempDataView en fixant le Marks selon le tempDataView - Nom par rapport à tempData - Nom

Oui, laissez-moi vous montrer ce que j'ai essayé, j'ai essayé de résoudre ce problème en utilisant le curseur et cela s'est parfaitement déroulé, mais je trouve le moyen de le résoudre en utilisant la fonction Sous-requête

C'est ici :

Declare @name varchar(50),@marks varchar(50)
Declare @cursorInsert CURSOR
set @cursorInsert = CURSOR FOR
Select name,marks from tempData
OPEN @cursorInsert
FETCH NEXT FROM @cursorInsert
into @name,@marks
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE tempDataView set marks = @marks where name = @name
FETCH NEXT FROM @cursorInsert
INTO @name,@marks
END
CLOSE @cursorInsert
DEALLOCATE @cursorInsert

En fait, c'est comme un devoir pour moi de le résoudre en utilisant la sous-requête.

207voto

John Woo Points 132738

Vous pouvez joindre les deux tables même sur UPDATE déclarations,

UPDATE  a
SET     a.marks = b.marks
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

pour des performances plus rapides, définissez un INDEX sur la colonne marks sur les deux tables.

en utilisant SUBQUERY

UPDATE  tempDataView 
SET     marks = 
        (
          SELECT marks 
          FROM tempData b 
          WHERE tempDataView.Name = b.Name
        )

42voto

cha Points 9518

Comme vous venez d'apprendre, je vous suggère de vous entraîner à convertir des jointures SELECT en jointures UPDATE ou DELETE. Tout d'abord, je vous suggère de générer une instruction SELECT joignant ces deux tables :

SELECT *
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

Ensuite, notez que nous avons deux alias de table a y b . En utilisant ces alias, vous pouvez facilement générer une instruction UPDATE pour mettre à jour la table a ou b. Pour la table a, vous avez une réponse fournie par JW. Si vous voulez mettre à jour b la déclaration sera :

UPDATE  b
SET     b.marks = a.marks
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

Maintenant, pour convertir la déclaration en une déclaration DELETE, utilisez la même approche. L'instruction ci-dessous supprimera de a uniquement (en laissant b intact) pour les enregistrements qui correspondent par le nom :

DELETE a
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

Vous pouvez utiliser le SQL Fiddle créé par JW comme terrain de jeu.

12voto

sfranco Points 121

Dans mon échantillon, j'ai trouvé la solution, car j'ai eu le même problème avec les mises à jour et les subquerys :

UPDATE
    A
SET
    A.ValueToChange = B.NewValue
FROM
    (
        Select * From C
    ) B
Where 
    A.Id = B.Id

1voto

Graham Laight Points 321

Le titre de ce fil de discussion demande comment une sous-requête peut être utilisée dans une mise à jour. Voici un exemple :

update [dbName].[dbo].[MyTable] 
set MyColumn = 1 
where 
    (
        select count(*) 
        from [dbName].[dbo].[MyTable] mt2 
        where
            mt2.ID > [dbName].[dbo].[MyTable].ID
            and mt2.Category = [dbName].[dbo].[MyTable].Category
    ) > 0

-1voto

Memin Points 1

Ici est une bonne explication de l'opération de mise à jour avec quelques exemples. Bien qu'il s'agisse d'un site Postgres, les requêtes SQL sont également valables pour les autres bases de données. Les exemples suivants sont intuitifs à comprendre.

-- Update contact names in an accounts table to match the currently assigned salesmen:

UPDATE accounts SET (contact_first_name, contact_last_name) =
    (SELECT first_name, last_name FROM salesmen
     WHERE salesmen.id = accounts.sales_id);

-- A similar result could be accomplished with a join:

UPDATE accounts SET contact_first_name = first_name,
                    contact_last_name = last_name
  FROM salesmen WHERE salesmen.id = accounts.sales_id;

Cependant, la deuxième requête peut donner des résultats inattendus si salesmen.id n'est pas une clé unique, alors que la première requête est garantie de soulever une erreur s'il y a plusieurs correspondances d'id. De plus, s'il n'y a pas de correspondance pour une entrée accounts.sales_id particulière, la première requête mettra les champs de nom correspondants à NULL, alors que la deuxième requête ne mettra pas du tout à jour cette ligne.

Ainsi, pour l'exemple donné, la requête la plus fiable est la suivante.

UPDATE tempDataView SET (marks) =
    (SELECT marks FROM tempData
     WHERE tempDataView.Name = tempData.Name);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X