Scénario:
Disons que j'ai deux tables, TableA et TableB. La clé primaire de TableB est une colonne unique (BId) et est une colonne de clé étrangère dans TableA.
Dans ma situation, je veux supprimer toutes les lignes de TableA qui sont liées à des lignes spécifiques de TableB: Puis-je le faire via des jointures? Supprimer toutes les lignes extraites des jointures?
DELETE FROM TableA
FROM
TableA a
INNER JOIN TableB b
ON b.BId = a.BId
AND [my filter condition]
Ou suis-je obligé de faire ceci:
DELETE FROM TableA
WHERE
BId IN (SELECT BId FROM TableB WHERE [my filter condition])
La raison pour laquelle je pose cette question est qu’il me semble que la première option serait beaucoup plus efficace lorsqu’il s’agit de tables plus grandes.
Merci!
DELETE TableA
FROM TableA a
INNER JOIN TableB b
ON b.Bid = a.Bid
AND [my filter condition]
devrait marcher
J'utiliserais cette syntaxe
Delete a
from TableA a
Inner Join TableB b
on a.BId = b.BId
WHERE [filter condition]
Oui, vous pouvez. Exemple :
DELETE TableA
FROM TableA AS a
INNER JOIN TableB AS b
ON a.BId = b.BId
WHERE [filter condition]
J'essayais de faire cela avec une base de données d’accès et j’ai trouvé qu’il me fallait utiliser a. * juste après la suppression.
DELETE a.*
FROM TableA AS a
INNER JOIN TableB AS b
ON a.BId = b.BId
WHERE [filter condition]
C'est presque la même chose dans MySQL, mais vous devez utiliser le alias de table juste après le mot "DELETE":
DELETE a
FROM TableA AS a
INNER JOIN TableB AS b
ON a.BId = b.BId
WHERE [filter condition]
J'utilise ceci
DELETE TableA
FROM TableA a
INNER JOIN
TableB b on b.Bid = a.Bid
AND [condition]
et @TheTXI way est suffisant, mais je lis les réponses et les commentaires et j’ai trouvé qu’une chose doit être résolue, c’est d’utiliser la condition dans la clause WHERE ou comme condition de jointure. J'ai donc décidé de le tester et d'écrire un extrait mais je n'ai pas trouvé de différence significative entre eux. Vous pouvez voir le script SQL ici et le point important est que j'ai préféré l'écrire en commnet car ce n'est pas une réponse exacte, mais il est volumineux et ne peut pas être mis en commentaire, veuillez me pardonner.
Declare @TableA Table
(
aId INT,
aName VARCHAR(50),
bId INT
)
Declare @TableB Table
(
bId INT,
bName VARCHAR(50)
)
Declare @TableC Table
(
cId INT,
cName VARCHAR(50),
dId INT
)
Declare @TableD Table
(
dId INT,
dName VARCHAR(50)
)
DECLARE @StartTime DATETIME;
SELECT @startTime = GETDATE();
DECLARE @i INT;
SET @i = 1;
WHILE @i < 1000000
BEGIN
INSERT INTO @TableB VALUES(@i, 'nameB:' + CONVERT(VARCHAR, @i))
INSERT INTO @TableA VALUES(@i+5, 'nameA:' + CONVERT(VARCHAR, @i+5), @i)
SET @i = @i + 1;
END
SELECT @startTime = GETDATE()
DELETE a
--SELECT *
FROM @TableA a
Inner Join @TableB b
ON a.BId = b.BId
WHERE a.aName LIKE '%5'
SELECT Duration = DATEDIFF(ms,@StartTime,GETDATE())
SET @i = 1;
WHILE @i < 1000000
BEGIN
INSERT INTO @TableD VALUES(@i, 'nameB:' + CONVERT(VARCHAR, @i))
INSERT INTO @TableC VALUES(@i+5, 'nameA:' + CONVERT(VARCHAR, @i+5), @i)
SET @i = @i + 1;
END
SELECT @startTime = GETDATE()
DELETE c
--SELECT *
FROM @TableC c
Inner Join @TableD d
ON c.DId = d.DId
AND c.cName LIKE '%5'
SELECT Duration = DATEDIFF(ms,@StartTime,GETDATE())
Si vous pouviez obtenir de bonnes raisons à partir de ce script ou en écrire un autre utile, veuillez le partager. Merci et espérons cette aide.
La syntaxe ci-dessus ne fonctionne pas dans Interbase 2007. Au lieu de cela, je devais utiliser quelque chose comme:
DELETE FROM TableA a WHERE [filter condition on TableA]
AND (a.BId IN (SELECT a.BId FROM TableB b JOIN TableA a
ON a.BId = b.BId
WHERE [filter condition on TableB]))
(Remarque: Interbase ne prend pas en charge le mot clé AS pour les alias)
vous pouvez lancer cette requête: -
Delete from TableA
from
TableA a, TableB b
where a.Bid=b.Bid
AND [my filter condition]
Supposons que vous avez 2 tables, une avec un ensemble principal (par exemple, Employees) et une avec un ensemble enfant (par exemple, des personnes à charge) et que vous souhaitez supprimer toutes les lignes de données de la table des personnes à charge qui ne peuvent pas être saisies. avec toutes les lignes de la table principale.
delete from Dependents where EmpID in (
select d.EmpID from Employees e
right join Dependents d on e.EmpID = d.EmpID
where e.EmpID is null)
Le point à noter ici est que vous collectez simplement un "tableau" d'empID à partir de la jointure en premier, l'utilisation de cet ensemble d'empID pour effectuer une opération de suppression sur la table Dépendants.
Dans SQLite, la seule chose qui fonctionne est similaire à la réponse de beauXjames.
Cela semble descendre à cette DELETE FROM table1 WHERE table1.col1 IN (SOME TEMPORARY TABLE);
et que certaines tables temporaires peuvent être créées par SELECT et JOIN vos deux tables et que vous pouvez filtrer cette table temporaire en fonction de la condition voulant que vous vouliez supprimer les enregistrements de Table1.
Le moyen le plus simple est:
DELETE TableA
FROM TableB
WHERE TableA.ID = TableB.ID