如何使用INER JOIN与SQL Server删除?

net*_*493 1181 sql sql-server inner-join sql-server-2008 sql-delete

我想INNER JOINSQL Server 2008中删除使用.

但我得到这个错误:

消息156,级别15,状态1,行15
关键字"INNER"附近的语法不正确.

我的代码:

DELETE FROM WorkRecord2 
INNER JOIN Employee ON EmployeeRun=EmployeeNo
WHERE Company = '1' AND Date = '2013-05-06'
Run Code Online (Sandbox Code Playgroud)

Tar*_*ryn 2083

您需要指定要删除的表,这是带别名的版本:

DELETE w
FROM WorkRecord2 w
INNER JOIN Employee e
  ON EmployeeRun=EmployeeNo
WHERE Company = '1' AND Date = '2013-05-06'
Run Code Online (Sandbox Code Playgroud)

  • 如果要从表中删除,请使用DELETE w,e FROM WorkRecord2 w INNER JOIN Employee e ON EmployeeRun = EmployeeNo Company ='1'AND Date ='2013-05-06' (137认同)
  • @PragneshMca该语法不适用于SQL Server. (76认同)
  • @ user2070775在SQL Server中从2个表中删除需要使用2个单独的语句. (39认同)
  • @bluefeet是否可以为SQL Server提供正确的语法以从两个表中删除? (8认同)
  • 在SQL Server中@ user2070775,您可以使用事务和伪表,如http://stackoverflow.com/questions/783726/how-do-i-delete-from-multiple-tables-using-inner-join-在-SQL服务器 (7认同)
  • @MathieuRodic 感谢分享。在我的设置中,如果我分别从 2 个表中删除,我真的不知道要从第二个表中删除哪些行,所以这会有所帮助:) (3认同)
  • @ShahryarSaljoughi是WorkRecord2表的别名。 (2认同)

him*_*056 134

只需添加的表名DELETE,并FROM从那里你要删除的记录,因为我们必须指定表中删除.还删除ORDER BY子句,因为删除记录时无需订购.

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

    DELETE WorkRecord2 
      FROM WorkRecord2 
INNER JOIN Employee 
        ON EmployeeRun=EmployeeNo
     WHERE Company = '1' 
       AND Date = '2013-05-06';
Run Code Online (Sandbox Code Playgroud)

  • 如果您只打算从第一个表中删除,则此选项在SQL Server上有效。 (3认同)
  • @matwonk:如果您使用第二个表的名称,则可以从第二个表中删除。例如,使用`DELETE Employee` 将从Employee 的表而不是`WorkRecord2` 表中删除。 (2认同)
  • @matwonk:这是一个例子:1)[从第一个表中删除](http://www.sqlfiddle.com/#!18/7c2ea/1)2)[从第二个表中删除](http:// www.sqlfiddle.com/#!18/7c2ea/2)。 (2认同)

Dev*_*art 29

这可能对你有所帮助 -

DELETE FROM dbo.WorkRecord2 
WHERE EmployeeRun IN (
    SELECT e.EmployeeNo
    FROM dbo.Employee e
    WHERE ...
)
Run Code Online (Sandbox Code Playgroud)

或试试这个 -

DELETE FROM dbo.WorkRecord2 
WHERE EXISTS(
    SELECT 1
    FROM dbo.Employee e
    WHERE EmployeeRun = e.EmployeeNo
        AND ....
)
Run Code Online (Sandbox Code Playgroud)

  • 这是适用于 SQL Server 的众多答案之一。我建议将接受的答案作为最好的方法。 (4认同)
  • 这是唯一适用于 Sql Server 的答案。只需构建您的查询,例如 select Id from... join ... join 等然后将其包装为子查询并从(表)中删除(子查询)中的 Id (2认同)

小智 27

试试这个:

DELETE FROM WorkRecord2 
       FROM Employee 
Where EmployeeRun=EmployeeNo
      And Company = '1' 
      AND Date = '2013-05-06'
Run Code Online (Sandbox Code Playgroud)


小智 14

它应该是:

DELETE zpost 
FROM zpost 
INNER JOIN zcomment ON (zpost.zpostid = zcomment.zpostid)
WHERE zcomment.icomment = "first"       
Run Code Online (Sandbox Code Playgroud)


Raf*_*ier 12

您甚至可以进行子查询。就像下面这段代码:

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


小智 10

在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
Run Code Online (Sandbox Code Playgroud)

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

现在将SELECT更改为DELETE:

DELETE Contact
FROM Contact
INNER JOIN Bedrijf ON Bedrijf.IDBedrijf = Contact.IDbedrijf
Run Code Online (Sandbox Code Playgroud)

您将在SELECT语句中看到的所有记录都将被删除.

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

DELETE FROM Contact
INNER JOIN Bedrijf ON Bedrijf.IDBedrijf = Contact.IDbedrijf
INNER JOIN LoginBedrijf ON Bedrijf.IDLoginBedrijf = LoginBedrijf.IDLoginBedrijf
Run Code Online (Sandbox Code Playgroud)


Aus*_*nTX 9

这个版本应该有效

DELETE WorkRecord2
FROM WorkRecord2 
INNER JOIN Employee ON EmployeeRun=EmployeeNo
Where Company = '1' AND Date = '2013-05-06'
Run Code Online (Sandbox Code Playgroud)


Ali*_*Ali 8

试试这个查询:

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';
Run Code Online (Sandbox Code Playgroud)

  • 我很确定DELETE只能指定一个表.这对我不起作用. (8认同)
  • 我相信您可以在mySQL中指定多个要删除的表,但不能指定SQL Server(该问题会问到)。 (3认同)

小智 8

 DELETE a FROM WorkRecord2 a 
       INNER JOIN Employee b 
       ON a.EmployeeRun = b.EmployeeNo 
       Where a.Company = '1' 
       AND a.Date = '2013-05-06'
Run Code Online (Sandbox Code Playgroud)

  • 很好,但希望对您的代码进行一些解释。 (4认同)

Pரத*_*ீப் 6

使用的另一种方式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 
Run Code Online (Sandbox Code Playgroud)

注意:如果需要,我们不能JOIN在内部使用。CTEdelete


小智 6

试试这个,可能会有所帮助

 DELETE WorkRecord2 
          FROM WorkRecord2 
    INNER JOIN Employee 
            ON EmployeeRun=EmployeeNo
         WHERE Company = '1' 
           AND Date = '2013-05-06';
Run Code Online (Sandbox Code Playgroud)

  • 它与接受的答案有何不同:/sf/ask/1153696561/#16481475? (6认同)
  • 该答案使用显式表命名而不是别名,使那些经验不足的人更容易阅读/掌握正在发生的事情。 (3认同)

one*_*hen 5

您没有为Companyand指定表Date,您可能想要解决这个问题。

标准 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;
Run Code Online (Sandbox Code Playgroud)

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

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

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

对我来说,各种专有语法答案更难阅读和理解。我想在frans eilering 的回答中最好地描述了的心态,即编写代码的人不一定关心将阅读和维护代码的人。


PPJ*_*PJN 5

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

DELETE           w
FROM             WorkRecord2   w,
                 Employee      e
WHERE            w.EmployeeRun = e.EmployeeNo
             AND w.Company = '1' 
             AND w.Date = '2013-05-06'
Run Code Online (Sandbox Code Playgroud)


Rah*_*was 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;
Run Code Online (Sandbox Code Playgroud)

请从网址检查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;
Run Code Online (Sandbox Code Playgroud)

请从网址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;
Run Code Online (Sandbox Code Playgroud)

请从网址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'
Run Code Online (Sandbox Code Playgroud)

请从网址检查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
Run Code Online (Sandbox Code Playgroud)

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

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