2009-07-24 8 views
6

Je dois créer une instruction SQL pour supprimer de certaines tables les enregistrements qui correspondent à une autre instruction select.Sql server DELETE et WITH clause

Dans Teradata nous utilisons

delete from table1 
where (col1, col2) in (
    select col1,col2 
    from table2 
) 

Alors que dans SQL Server, il est pas permis d'avoir plus de 1 colonne dans la clause WHERE..IN. Je pensais pouvoir utiliser la clause WITH:

with tempTable(col1,col2) as (
select col1,col2 
from table2 
) 
delete from table1 
where table1.col1 = tempTable.col1 
and table1.col2 = tempTable.col2 

Comment utiliser la clause WITH..DELETE? Y a-t-il un autre moyen?

Répondre

19

Cela devrait le faire:

DELETE Table1 
from Table1 t1 
    inner join tempTable t2 
    on t2.Col1 = t1.Col1 
    and t2.Col2 = t1.Col2 
+1

... vous pouvez utiliser la Clause WITH, mais de cette façon est plus simple. –

+0

merci cela a fonctionné! mais comment utiliser WITH..DELETE? – ala

+0

En y réfléchissant, je ne vois aucune raison d'utiliser la clause WITH. J'utilise WITH lorsque les choses deviennent vraiment compliquées ou complexes, et la suppression d'une table basée sur une simple jointure à une autre table n'est pas assez complexe pour justifier l'effort de codage supplémentaire. –

1
delete from table1 t1 where exists 
    ( 

    select 1 from table2 t2 where t1.col1 = t2.col1 and t1.col2 > t2.col2 

) 
+1

Cette syntaxe est incorrecte –

+1

la syntaxe est incorrecte, mais l'idée générale est correcte. SQL Server peut optimiser cela de sorte qu'il devrait fonctionner aussi bien qu'une solution utilisant une jointure tout en étant plus facile à lire. – EvilRyry

4

d'abord construire une requête qui sélectionne les lignes dont vous avez besoin:

SELECT t1.* 
FROM [Table1] t1 
INNER JOIN [Table2] t2 ON t1.[col1] = t2.[col1] AND t1.[Col2]=t2.[Col2] 

Testez pour vous assurer qu'il retourne exactement les lignes que vous vouloir supprimer. Ensuite, tournez dans une déclaration de suppression en modifiant la « SELECT » pour « DELETE » et la suppression de la liste des colonnes:

DELETE t1 
FROM [Table1] t1 
INNER JOIN [Table2] t2 ON t1.[col1] = t2.[col1] AND t1.[Col 
+0

C'est un bon conseil dans SSMS, mais pas très pratique programmatique .... – RolandTumble

+1

+1 pour mesurer deux fois et couper une fois – 2Toad

0
with tempTable(col1,col2) as (
    select col1,col2 
    from table2 
) 
delete table1 from tempTable 
where table1.col1 = tempTable.col1 
and table1.col2 = tempTable.col2 
+1

Il est toujours préférable d'inclure quelques explications plutôt que de simplement avoir une réponse uniquement au code car cela le rend plus utile à l'avenir lecteurs. – EJoshuaS

+0

Bienvenue dans Stack Overflow! Bien que cet extrait de code puisse résoudre le problème, il n'explique ni pourquoi ni comment il répond à la question. S'il vous plaît [inclure une explication pour votre code] (// meta.stackexchange.com/q/114762/269535), car cela aide vraiment à améliorer la qualité de votre message. Rappelez-vous que vous répondez à la question pour les lecteurs dans le futur, et que ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. ** Flaggers/reviewers: ** [Pour les réponses au code comme celui-ci, downvote, ne pas supprimer!] (// meta.stackoverflow.com/a/260413/2747593) –

0

Cela fonctionne pour moi

WITH CTE AS 
(
SELECT TOP 50000 * 
from v020101hist order by data 
) 
DELETE FROM CTE