如何在 SQL Server 中使用 INNER JOIN 进行删除?

How can I delete using INNER JOIN with SQL Server?

提问人:nettoon493 提问时间:5/10/2013 最后编辑:Rahul Biswasnettoon493 更新时间:10/3/2021 访问量:2067307

问:

我想 SQL Server 2008 中删除 use。INNER JOIN

但是我收到这个错误:

消息 156,级别 15,状态 1,第 15
关键字“INNER”附近的语法不正确

我的代码:

DELETE 
FROM WorkRecord2 
INNER JOIN Employee 
        ON EmployeeRun=EmployeeNo
WHERE Company = '1' 
    AND Date = '2013-05-06'
sql-server sql-server-2008 内部联接 sql-delete

评论

4赞 Pondlife 5/10/2013
文档中的示例 C 显示了如何与联接一起使用DELETE
5赞 reggaeguitar 1/28/2020
示例 C 也使用光标和一堆无关的东西
3赞 Jun Yu 1/18/2022
示例 D:使用对一个表中的数据的联接和子查询来删除另一个表中的行可能是正确的方法。

答:

2925赞 Taryn 5/10/2013 #1

您需要指定要从中删除的表。下面是一个带有别名的版本:

DELETE w
FROM WorkRecord2 w
INNER JOIN Employee e
  ON EmployeeRun=EmployeeNo
WHERE Company = '1' AND Date = '2013-05-06'

评论

9赞 dev4life 5/21/2014
@bluefeet能否为 SQL Server 提供正确的语法以从两个表中删除?
64赞 Taryn 5/27/2014
@user2070775 在 SQL Server 中,要从 2 个表中删除,需要使用 2 个单独的语句。
10赞 Mathieu Rodic 6/2/2014
@user2070775 SQL Server 中,可以使用事务和伪表,如 stackoverflow.com/questions/783726/...
4赞 Verena Praher 8/24/2016
@MathieuRodic感谢您的分享。在我的设置中,如果我分别从 2 个表中删除,我真的不知道要从第二个表中删除哪一行,所以这将有助于:)
2赞 Taryn 4/29/2018
@ShahryarSaljoughi这是 WorkRecord2 表的别名。
221赞 Himanshu 5/10/2013 #2

只需在要删除记录的位置之间和位置添加表的名称,因为我们必须指定要删除的表。此外,删除该子句,因为在删除记录时没有任何内容可排序。DELETEFROMORDER BY

因此,您的最终查询应如下所示:

    DELETE WorkRecord2 
      FROM WorkRecord2 
INNER JOIN Employee 
        ON EmployeeRun=EmployeeNo
     WHERE Company = '1' 
       AND Date = '2013-05-06';

评论

4赞 TroySteven 12/22/2018
如果您只打算从第一个表中删除,则此表适用于 SQL Server。
2赞 Himanshu 12/22/2018
@matwonk:如果使用第二个表的名称,则可以从第二个表中删除。例如,using 将从 Employee 的表中删除,而不是从表中删除。DELETE EmployeeWorkRecord2
2赞 Himanshu 5/2/2019
@matwonk:下面是一个示例:1)从第一个表中删除 2)从第二个表中删除
1赞 Daniel 4/9/2021
如果要从将自身作为外键的表中删除(并且不使用级联删除),则删除顺序可能很重要。但我同意总的来说没关系......
44赞 Devart 5/10/2013 #3

这可能对您有所帮助 -

DELETE FROM dbo.WorkRecord2
WHERE EmployeeRun IN (
    SELECT e.EmployeeNo
    FROM dbo.Employee e
    WHERE ...
)

或者试试这个 -

DELETE FROM dbo.WorkRecord2
WHERE EXISTS(
    SELECT 1
    FROM dbo.Employee e
    WHERE EmployeeRun = e.EmployeeNo
        AND ....
)

评论

2赞 Chris Moschini 9/29/2015
这是唯一适用于 Sql Server 的答案。只需构建您的查询,例如从中选择 ID...加入。。。join etc 然后将其包装为子查询,并从 (table) 中删除 Id in (subquery)
4赞 Geoff Griswald 10/5/2020
这是适用于 SQL Server 的众多答案之一。我建议公认的答案是最好的方法。
32赞 Behrouz Bakhtiari 5/11/2013 #4

试试这个:

DELETE FROM WorkRecord2 
       FROM Employee 
Where EmployeeRun=EmployeeNo
      And Company = '1' 
      AND Date = '2013-05-06'
10赞 Ali 7/16/2014 #5

试试这个查询:

DELETE WorkRecord2, Employee 
FROM WorkRecord2 
INNER JOIN Employee ON (tbl_name.EmployeeRun=tbl_name.EmployeeNo)
WHERE tbl_name.Company = '1' 
AND tbl_name.Date = '2013-05-06';

评论

10赞 Stealth Rabbi 3/17/2015
我很确定 DELETE 只能指定一个表。这对我不起作用。
6赞 dandev91 12/20/2016
我相信您可以在 mySQL 中指定多个要删除的表,但不能指定 SQL Server(问题问)。
21赞 yoginder bagga 8/17/2014 #6

它应该是:

DELETE zpost 
FROM zpost 
INNER JOIN zcomment ON (zpost.zpostid = zcomment.zpostid)
WHERE zcomment.icomment = "first"       
23赞 frans eilering 6/2/2015 #7

SQL Server Management Studio 中,我可以轻松创建查询:SELECT

SELECT Contact.Naam_Contactpersoon, Bedrijf.BedrijfsNaam, Bedrijf.Adres, Bedrijf.Postcode
FROM Contact
INNER JOIN Bedrijf ON Bedrijf.IDBedrijf = Contact.IDbedrijf

我可以执行它,并显示我的所有联系人。

现在将 更改为 :SELECTDELETE

DELETE Contact
FROM Contact
INNER JOIN Bedrijf ON Bedrijf.IDBedrijf = Contact.IDbedrijf

您在对帐单中看到的所有记录都将被删除。SELECT

您甚至可以使用相同的过程创建更困难的内部连接,例如:

DELETE FROM Contact
INNER JOIN Bedrijf ON Bedrijf.IDBedrijf = Contact.IDbedrijf
INNER JOIN LoginBedrijf ON Bedrijf.IDLoginBedrijf = LoginBedrijf.IDLoginBedrijf

评论

0赞 KeyOfJ 6/29/2023
我最喜欢这个。人们缺少的是你必须在 DELETE AND FROM 语句之间使用表名,或者使用一个别名,你不能只拥有 DELETE FROM Contact INNER JOIN......
4赞 Andy 3/9/2016 #8

这是我的 SQL Server 版本

DECLARE @ProfileId table(Id bigint)

DELETE FROM AspNetUsers
OUTPUT deleted.ProfileId INTO @ProfileId
WHERE Email = @email

DELETE FROM UserProfiles    
WHERE Id = (Select Id FROM @ProfileId)
6赞 onedaywhen 5/19/2016 #9

您没有为 和 指定表,您可能希望解决此问题。CompanyDate

标准 SQL 使用:MERGE

MERGE WorkRecord2 T
   USING Employee S
      ON T.EmployeeRun = S.EmployeeNo
         AND Company = '1'
         AND Date = '2013-05-06'
WHEN MATCHED THEN DELETE;

Devart 的答案也是标准的 SQL,尽管不完整。它应该看起来更像这样:

DELETE
  FROM WorkRecord2
  WHERE EXISTS ( SELECT *
                   FROM Employee S
                  WHERE S.EmployeeNo = WorkRecord2.EmployeeRun
                        AND Company = '1'
                        AND Date = '2013-05-06' );

关于上述内容,需要注意的重要一点是,很明显,删除是针对单个表的,正如在第二个示例中通过要求标量子查询来强制执行的那样。

对我来说,各种专有语法答案更难阅读和理解。我想这种心态最好在弗兰斯·艾勒林的回答中描述,即编写代码的人不一定关心阅读和维护代码的人。

8赞 Pரதீப் 9/10/2016 #10

另一种方法是使用:CTE

;WITH cte
     AS (SELECT *
         FROM   workrecord2 w
         WHERE  EXISTS (SELECT 1
                        FROM   employee e
                        WHERE  employeerun = employeeno
                               AND company = '1'
                               AND date = '2013-05-06'))
DELETE FROM cte

注意:我们不能在你想的时候使用里面。JOINCTEdelete

6赞 PPJN 2/22/2017 #11

以下是我目前用于删除甚至更新的内容:

DELETE           w
FROM             WorkRecord2   w,
                 Employee      e
WHERE            w.EmployeeRun = e.EmployeeNo
             AND w.Company = '1' 
             AND w.Date = '2013-05-06'
4赞 Ady 5/10/2017 #12

这是一个简单的查询,用于一次从两个表中删除记录。

DELETE table1.* ,
       table2.* 
FROM table1 
INNER JOIN table2 ON table1.id= table2.id where table1.id ='given_id'

评论

10赞 Darren Griffith 7/11/2018
此问题适用于 SQL Server。不能在 SQL Server 中的一个语句中删除两个表。我的理解是这可以在 mysql 和 MS Access 中完成。
12赞 Rafael Xavier 9/2/2020 #13

你甚至可以做一个子查询。如下代码所示:

DELETE FROM users WHERE id IN(
    SELECT user_id FROM Employee WHERE Company = '1' AND Date = '2013-05-06'
)
5赞 Rahul Biswas 10/3/2021 #14

使用事务块、表变量和 JOIN 删除多个表数据。

BEGIN TRANSACTION;

   declare @deletedIds table ( id int );
   
   DELETE w
   output deleted.EmployeeRun into @deletedIds
   FROM WorkRecord2 w
   INNER JOIN Employee e
           ON e.EmployeeNo = w.EmployeeRun
          AND w.Company = 1
          AND w.date = '2013-05-06';

   DELETE e
   FROM Employee as e
   INNER JOIN @deletedIds as d
           ON d.id = e.EmployeeNo;
COMMIT TRANSACTION;

请从网址 https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=43330dda6f1b71b8ec4172a24d5b6921 检查

使用临时表和 JOIN 删除多个表数据。删除后删除临时表。

BEGIN TRANSACTION;

    -- create temporary table
    create table #deletedRecords (employeeId int);
    
    -- INSERT INTO #deletedRecords
    SELECT e.EmployeeNo
    FROM WorkRecord2 w
    INNER JOIN Employee e
           ON e.EmployeeNo = w.EmployeeRun
          AND w.Company = 1
          AND w.date = '2013-05-06';
          
    -- delete from WorkRecord2
    DELETE w
    FROM WorkRecord2 w
    INNER JOIN #deletedRecords d
           ON w.EmployeeRun = d.employeeId;
           
    -- delete from Employee using exists
    DELETE 
    FROM Employee
    WHERE EXISTS (SELECT 1
                  FROM #deletedRecords d
                  WHERE d.employeeId = EmployeeNo);
                  
    -- drop temporary table
    DROP TABLE #deletedRecords;

COMMIT TRANSACTION;

请从网址 https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=d52c6c1ed91669d68fcc6bc91cb32d78 检查

使用 SELECT INTO 创建临时表的替代方法

BEGIN TRANSACTION;

    SELECT  e.EmployeeNo employeeId 
    INTO #deletedRecords
    FROM WorkRecord2 w
    INNER JOIN Employee e
           ON e.EmployeeNo = w.EmployeeRun
          AND w.Company = 1
          AND w.date = '2013-05-06';
          
    -- delete from WorkRecord2
    DELETE w
    FROM WorkRecord2 w
    INNER JOIN #deletedRecords d
           ON w.EmployeeRun = d.employeeId;
           
    -- delete from Employee using exists
    DELETE 
    FROM Employee
    WHERE EXISTS (SELECT 1
                  FROM #deletedRecords d
                  WHERE d.employeeId = EmployeeNo);
                  
    -- drop temporary table
    DROP TABLE #deletedRecords;

COMMIT TRANSACTION;

请从网址 https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=0f02f05616ce5b4dcc8fc67c6cf1e640 检查

使用 JOIN 删除单个表数据

DELETE w
FROM WorkRecord2 w
INNER JOIN Employee e
        ON e.EmployeeNo = w.EmployeeRun
       AND w.Company = 1
       AND w.date = '2013-05-06'

请从网址 https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=84a60d1368556a8837281df36579334a 检查

使用 CTE 删除单表数据

WITH cte AS (
     SELECT w.EmployeeRun
     FROM WorkRecord2 w
     WHERE EXISTS (SELECT 1
                   FROM Employee 
                   WHERE EmployeeNo = w.EmployeeRun)
         AND w.Company = 1
         AND w.date = '2013-05-06'
)
DELETE
FROM cte

请从网址 https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=6590007b3c8c2ffad5563bd86606c5b1 检查

在子表中创建外键期间使用 ON CASCADE DELETE。如果删除父表数据,则会自动删除相应的子表数据。