2012-03-29 5 views
2

J'essaie d'écrire une sous-requête corrélée simple qui supprime tous les enregistrements pour les membres sélectionnés sauf le dernier.Pourquoi cette sous-requête simple ne fonctionne-t-elle pas?

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) 

Mais je reçois une syntaxe incorrecte message d'erreur

près de 'p'.

Je peux facilement écrire 3 requêtes pour faire le travail. Mais était curieux de savoir ce qui ne va pas ici? Pourriez-vous s'il vous plaît m'éclairer comment écrire cette requête correctement?

Merci à l'avance

Répondre

2

Essayez

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

Merci John .. Mais cela n'a pas fonctionné..Même erreur "Syntaxe incorrecte près de 'p'." – Ananth

+1

@Ananth: Il n'y a * absolument * aucune erreur de syntaxe dans cette réponse, cela a parfaitement fonctionné pour moi. Vous devez avoir manqué quelque chose en l'appliquant à votre vraie table. –

+0

@Andiry, John. Query fonctionne très bien .. Il était mon mauvais .. Merci beaucoup :) – Ananth

1

Et utiliser certains Alias ​​pour les tables:

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

Ne va pas au travail - L'erreur se produit parce que vous ne pouvez pas avoir un alias sur la table DELETE FROM –

+0

Bien sûr, vous avez raison! Je me souviens, j'ai eu un tel problème il ya longtemps ;-) – Tobi

1

Essayez de suivre

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

J'ai essayé ceci ceci ne devrait pas donner une erreur. – chamara

+0

Non, il ne devrait pas, mais votre suggestion est une réplique complète de @ John Dewey. –

2

Comme alternative, vous pourriez alias la table dans la sous-requête et référence l'instance externe de member_id par nom de la table:

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) 

Dans SQL Server, lorsque vous attribuez un alias à une table, vous ne pouvez plus faire référence cette table par son nom d'origine dans le même déclaration. Ainsi, en préfixant les colonnes avec table1. dans la sous-requête, vous référeriez certainement la table externe.

+0

+1 Ceci est la manière la plus logique: cibler la variable 'DELETE' sur la variable range ('alias')' p' en théorie devrait laisser la table de base inchangée, ce qui n'est clairement pas l'intention. – onedaywhen

+0

Merci. Je pense que aliasing la table externe a un sens aussi, au moins quand le nom est particulièrement long (et on est particulièrement paresseux) :) –

Questions connexes