2012-03-29 18 views
2

Ich versuche, eine einfache korrelierte Unterabfrage zu schreiben, die alle Datensätze für die ausgewählten Mitglieder außer dem letzten löscht.Warum funktioniert diese einfache Unterabfrage nicht?

DELETE FROM table1 p 
WHERE member_id IN (1, 2,3) 
AND create_dttm < (SELECT MAX(create_dttm) 
        FROM table1 
        WHERE member_id = p.member_id) 

aber ich erhalte eine Fehlermeldung

falsche Syntax in der Nähe von 'p'.

Ich kann leicht 3 Abfragen schreiben, um die Arbeit zu erledigen. Aber war neugierig zu erfahren, was hier schief läuft? Könntest du mir bitte erklären, wie man diese Abfrage richtig schreibt?

Vielen Dank im Voraus

Antwort

2

DELETE p 
FROM table1  p 
WHERE member_id IN (1, 2,3) 
AND create_dttm < (SELECT MAX(create_dttm) 
                   FROM table1   
                   WHERE  member_id = p.member_id) 
+0

Dank John .. Aber das hat nicht funktioniert ..Seim Fehler "Falsche Syntax in der Nähe von 'p'." – Ananth

+1

@Ananth: Es gibt * absolut * keinen Syntaxfehler in dieser Antwort, es hat für mich vollkommen funktioniert. Sie müssen etwas übersehen haben, wenn Sie es auf Ihren realen Tisch anwenden. –

+0

@Anndiry, John. Query funktioniert gut .. Es war mein schlechtes .. Vielen Dank :) – Ananth

1

Versuchen und einige Alias ​​für die Tabellen verwenden:

DELETE FROM table1 p 
WHERE p.member_id IN (1, 2,3) 
AND p.create_dttm < (SELECT MAX(p1.create_dttm) 
        FROM table1 p1 
        WHERE p1.member_id = p.member_id) 
+1

Nicht zur Arbeit gehen - Der Fehler tritt auf, weil Sie keinen Alias ​​für die DELETE FROM-Tabelle haben können –

+0

Sicher, Sie sind richtig! Ich erinnere mich, ich hatte so ein Problem vor langer Zeit ;-) – Tobi

1

Versuchen

DELETE p FROM table1 p 
WHERE member_id IN (1, 2,3) 
AND create_dttm < (SELECT MAX(create_dttm) 
        FROM table1 
        WHERE member_id = p.member_id) 
+0

Ich habe versucht, dies sollte nicht einen Fehler geben. – chamara

+0

Nein, sollte es nicht, aber Ihr Vorschlag ist eine vollständige Replik von @ John Dewey. –

2

Als Alternative folgenden, könnten Sie alias die Tabelle in der Unterabfrage und verweisen die member_id die äußere Instanz durch den realen Namen der Tabelle:

DELETE FROM table1 
WHERE WHERE member_id IN (1, 2,3) 
AND create_dttm < (SELECT MAX(create_dttm) 
        FROM table1 p 
        WHERE table1.member_id = p.member_id) 

In SQL Server, wenn Sie einen Alias ​​zu einer Tabelle zuweisen, die Sie nicht mehr, dass die Tabelle in der durch seinen ursprünglichen Namen verweisen können gleiche Aussage. Wenn Sie also in der Unterabfrage Spalten mit table1. voranstellen, würden Sie sicherlich auf die äußere Tabelle verweisen.

+0

+1 Dies ist der logischste Weg: Targeting der 'DELETE' bei der Bereichsvariable ('Alias')' P' in der Theorie sollte die Basistabelle unberührt lassen., Eindeutig nicht die Absicht. – onedaywhen

+0

Danke. Ich finde Aliasing der äußeren Tabelle auch sinnvoll, zumindest wenn der Name besonders lang ist (und man ist besonders faul) :) –

Verwandte Themen