如何在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个回答

6

您没有指定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' );

重要的一点是要注意以上内容清楚地指出删除操作针对单个表,正如第二个示例所要求的标量子查询一样。
对于我来说,各种专有语法的答案更难阅读和理解。我猜想最好用frans eilering的回答来描述这种思维方式,即编写代码的人并不一定关心将来会读和维护代码的人。

5
使用事务块、表变量和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'

请从URL 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。如果删除父表数据,则相应的子表数据将自动删除。

4

这是我的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)

4

这是一个简单的查询,可以同时从两个表中删除记录。

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

10
这个问题是关于SQL Server的。在SQL Server中,你不能在一条语句中从两个表中删除记录。我的理解是,在mysql和MS Access中是可以这样做的。 - Darren Griffith

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