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

1723

我想在SQL Server 2008中使用INNER JOIN来进行删除操作。

但是我遇到了这个错误:

Msg 156, Level 15, State 1, Line 15
关键字'INNER' 附近的语法错误。

我的代码:

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

4
文档中的示例 C 展示了如何使用 DELETE 与连接一起使用。 - Pondlife
5
示例C使用了一个光标和一堆不必要的东西。 - reggaeguitar
3
使用连接和子查询将一个表中的数据用于删除另一个表中的行,可能是正确的方法。 - Jun Yu
14个回答

2918

您需要指定从哪个表中删除数据。以下是带有别名的版本:

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

9
@bluefeet,你能为SQL Server提供删除两个表中数据的正确语法吗? - dev4life
64
在 SQL Server 中,要从2个表中删除数据,需要使用2条单独的语句。 - Taryn
10
在 SQL Server 中,你可以使用事务和伪表来完成操作,具体方法请参考 https://dev59.com/FnRA5IYBdhLWcg3w6SXZ。 - Mathieu Rodic
4
谢谢分享,如果我单独从这两个表中删除数据,那么我就不知道应该从第二个表中删除哪些行数据,所以这对我很有帮助 :) - Verena Haunschmid
2
@ShahryarSaljoughi 是 WorkRecord2 表的别名。 - Taryn
显示剩余6条评论

221

只需在 DELETEFROM 之间添加要删除记录的表名,因为我们必须指定要删除的表。同时移除 ORDER BY 子句,因为在删除记录时不需要排序。

所以你最终的查询应该像这样:

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

4
如果您只打算从第一个表中删除数据,那么这个方法适用于 SQL Server。 - TroySteven
2
@matwonk:如果您使用第二个表的名称,可以从第二个表中删除。例如,使用“DELETE Employee”将从Employee表中删除,而不是从“WorkRecord2”表中删除。 - Himanshu
2
@matwonk:这里是一个例子:1)从第一个表中删除 2)从第二个表中删除 - Himanshu
1
如果你从一个具有自身作为外键的表中删除(并且不使用级联删除),删除顺序可能很重要。但总体而言,我同意这并不重要... - Daniel

44

这可能会对您有所帮助 -

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
这是在Sql Server上唯一有效的答案。只需构建您的查询,如select Id from... join ... join等,然后将其包装为子查询,并执行delete from(table)where Id in(subquery)。 - Chris Moschini
4
这是适用于 SQL Server 的众多答案之一。我建议接受该答案,这是最佳的方法。 - Geoff Griswald

32

试试这个:

DELETE FROM WorkRecord2 
       FROM Employee 
Where EmployeeRun=EmployeeNo
      And Company = '1' 
      AND Date = '2013-05-06'

23

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

我可以执行它,而且我的所有联系人都会显示出来。

现在将 SELECT 更改为 DELETE


现在将 SELECT 更改为 DELETE

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

我最喜欢这个。人们忽略的是,在DELETE和FROM语句之间必须使用表名,或者使用别名,不能只写DELETE FROM Contact INNER JOIN... - KeyOfJ

21

应该是:

DELETE zpost 
FROM zpost 
INNER JOIN zcomment ON (zpost.zpostid = zcomment.zpostid)
WHERE zcomment.icomment = "first"       

12

你甚至可以做一个子查询。像下面的代码:

DELETE FROM users WHERE id IN(
    SELECT user_id FROM Employee WHERE Company = '1' AND Date = '2013-05-06'
)

10

尝试这个查询:

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
我很确定DELETE语句只能指定一张表,这对我来说行不通。 - Stealth Rabbi
6
我相信在mySQL中可以指定多个表进行删除操作,但在SQL Server中不行(这是问题所询问的)。 - dandev91

8
另一种方法是使用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

注意:当您想要删除时,不能在CTE中使用JOIN


6

这是我目前用于删除或更新的代码:

DELETE           w
FROM             WorkRecord2   w,
                 Employee      e
WHERE            w.EmployeeRun = e.EmployeeNo
             AND w.Company = '1' 
             AND w.Date = '2013-05-06'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接