2009-07-24 15 views
6

Potrzebuję zbudować instrukcję SQL, aby usunąć z pewnej tabeli rekordy pasujące do innej instrukcji select.Sql server DELETE i WITH klauzula

W Teradata używamy

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

Choć w SQL Server to nie może mieć więcej niż 1 kolumny w klauzuli WHERE..IN. Myślałem, że mogę użyć klauzula WITH:

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

Jak używać klauzuli WITH..DELETE? Czy istnieje inny sposób?

Odpowiedz

19

ten powinien zrobić:

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

... można użyć Z klauzulą, ale ten sposób jest prostszy. –

+0

dziękuję! ale jak używać WITH..DELETE? – ala

+0

Myśląc o tym, nie widzę powodu, aby używać klauzuli WITH. Używam WITH, gdy sytuacja staje się poważnie nieporządna lub skomplikowana, a usunięcie z tabeli opartej na prostym połączeniu z inną tabelą nie jest wystarczająco złożone, aby uzasadnić dodatkowe wysiłki związane z kodowaniem. –

1
delete from table1 t1 where exists 
    ( 

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

) 
+1

Ta składnia jest niepoprawna –

+1

Składnia jest niepoprawny, ale ogólna idea jest poprawna. SQL Server może to zoptymalizować, tak aby działał równie dobrze jak rozwiązanie wykorzystujące sprzężenie, a jednocześnie łatwiejszy do odczytania. – EvilRyry

4

najpierw zbudować kwerendę, która wybiera wiersze musisz:

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

testowy to aby upewnić się, że wraca dokładnie wiersze, które chcę usunąć. Następnie przekształcić go w DELETE zmieniając „SELECT” na „Usuń” i usunięcie z listy kolumna:

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

To dobra rada w SSMS, ale niezbyt praktyczna programowalnie .... – RolandTumble

+1

+1 za pomiar podwójny i wycinanie raz – 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

Zawsze lepiej jest podać wyjaśnienie, niż po prostu uzyskać odpowiedź tylko kodu, ponieważ jest to bardziej przydatne w przyszłości czytelnicy. – EJoshuaS

+0

Witamy w Stack Overflow! Ten fragment kodu może rozwiązać problem, ale nie wyjaśnia, dlaczego i w jaki sposób odpowiada na pytanie. Proszę [załączyć wyjaśnienie swojego kodu] (// meta.stackexchange.com/q/114762/269535), ponieważ to naprawdę pomaga poprawić jakość twojego posta. Pamiętaj, że odpowiadasz na pytanie przeznaczone dla czytelników w przyszłości, a te osoby mogą nie znać powodów sugestii dotyczących kodu. ** Oznaczniki/recenzenci: ** [tylko dla odpowiedzi typu "tylko hasło", nie usuwaj!] (// meta.stackoverflow.com/a/260413/2747593) –

0

Działa to dla mnie

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