web-dev-qa-db-fra.com

Requête de mise à jour à l'aide d'une sous-requête dans SQL Server

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

Table 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 souhaite mettre à jour la table tempDataView en définissant marques en fonction de tempDataView - Nom par rapport à tempData. _ - Prénom

Oui, permettez-moi de vous montrer ce que j'ai essayé, j'ai essayé de résoudre ce problème en utilisant le curseur et sa résolution parfaitement, mais je suis en train de trouver le moyen de le résoudre en utilisant le 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. 

51
Narendra Pal

vous pouvez joindre les deux tables même sur des instructions UPDATE,

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 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
        )
118
John Woo

parce que vous venez d'apprendre, je vous suggère de vous entraîner à convertir une jointure SELECT en jointes 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

Puis notez que nous avons deux alias de table a et 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 souhaitez 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 l'instruction en une instruction DELETE, utilisez la même approche. La déclaration ci-dessous supprimera uniquement de a (en laissant b intact) les enregistrements qui correspondent par leur 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

25
cha

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

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
1
Graham Laight

Ici est une bonne explication de l'opération de mise à jour avec quelques exemples. Bien que ce soit le site Postgres, mais les requêtes SQL sont également valables pour les autres DB .. .. 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;

Toutefois, 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 génère une erreur s'il existe plusieurs correspondances d'identifiant. De même, s'il n'y a pas de correspondance pour une entrée accounts.sales_id particulière, la première requête définira les champs de nom correspondants sur NULL, tandis que la seconde requête ne mettra pas à jour cette ligne.

Par conséquent, pour l'exemple donné, la requête la plus fiable est comme suit. 

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