1739

I want to delete using INNER JOIN in SQL Server 2008.

But I get this error:

Msg 156, Level 15, State 1, Line 15
Incorrect syntax near the keyword 'INNER'.

My code:

DELETE 
FROM WorkRecord2 
INNER JOIN Employee 
        ON EmployeeRun=EmployeeNo
WHERE Company = '1' 
    AND Date = '2013-05-06'
3
  • 4
    Example C in the documentation shows how to use DELETE with a join
    – Pondlife
    May 10, 2013 at 14:22
  • 5
    Example C uses a cursor and a bunch of extraneous stuff too Jan 27, 2020 at 22:45
  • 3
    Example D Using joins and subqueries to data in one table to delete rows in another table may be the correct one.
    – Jun Yu
    Jan 18, 2022 at 5:42

14 Answers 14

2951

You need to specify what table you are deleting from. Here is a version with an alias:

DELETE w
FROM WorkRecord2 w
INNER JOIN Employee e
  ON EmployeeRun=EmployeeNo
WHERE Company = '1' AND Date = '2013-05-06'
12
  • 10
    @bluefeet could you provide the right syntax for SQL Server for deleting from both tables?
    – dev4life
    May 21, 2014 at 14:43
  • 65
    @user2070775 In SQL Server to delete from 2 tables you need to use 2 separate statements.
    – Taryn
    May 27, 2014 at 14:12
  • 10
    @user2070775 in SQL Server, you can use transactions and pseudo-tables, as shown in stackoverflow.com/questions/783726/… Jun 1, 2014 at 20:28
  • 4
    @MathieuRodic thanks for sharing. In my setup if I delete from the 2 tables separately I don't really know anymore which rows to delete from the 2nd table so this will help :) Aug 24, 2016 at 5:56
  • 2
    @ShahryarSaljoughi that is the alias for the WorkRecord2 table.
    – Taryn
    Apr 29, 2018 at 15:57
225

Just add the name of the table between DELETE and FROM from where you want to delete records, because we have to specify the table to delete. Also remove the ORDER BY clause because there is nothing to order while deleting records.

So your final query should be like this:

    DELETE WorkRecord2 
      FROM WorkRecord2 
INNER JOIN Employee 
        ON EmployeeRun=EmployeeNo
     WHERE Company = '1' 
       AND Date = '2013-05-06';
4
  • 4
    This one works on SQL Server if you only intend to delete from the first table.
    – TroySteven
    Dec 21, 2018 at 18:55
  • 2
    @matwonk: You can delete from second table to if you use second table's name. E.g. using DELETE Employee will delete from Employee's table instead of WorkRecord2 table.
    – Himanshu
    Dec 22, 2018 at 4:18
  • 2
    @matwonk: Here is an example: 1) Deleting from the first table 2) Deleting from the second table.
    – Himanshu
    May 2, 2019 at 10:52
  • 1
    Deletion order can matter if you are deleting from a table that has itself as a foreign key (And not using cascading delete.) But I agree in general it doesn't matter...
    – Daniel
    Apr 8, 2021 at 20:57
45

It is possible this will be helpful for you -

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

Or try this -

DELETE FROM dbo.WorkRecord2
WHERE EXISTS(
    SELECT 1
    FROM dbo.Employee e
    WHERE EmployeeRun = e.EmployeeNo
        AND ....
)
2
  • 2
    This is the only answer that works on Sql Server. Just build your query like select Id from... join ... join etc then wrap it as a subquery and do a delete from (table) where Id in (subquery) Sep 29, 2015 at 14:18
  • 4
    This is one of many answers that works on SQL Server. I suggest the accepted answer as the best way to do it. Oct 5, 2020 at 13:19
31

Try this:

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

In SQL Server Management Studio I can easily create a SELECT query:

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

I can execute it, and all my contacts are shown.

Now change the SELECT to a DELETE:

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

All the records you saw in the SELECT statement will be removed.

You may even create a more difficult inner join with the same procedure, for example:

DELETE FROM Contact
INNER JOIN Bedrijf ON Bedrijf.IDBedrijf = Contact.IDbedrijf
INNER JOIN LoginBedrijf ON Bedrijf.IDLoginBedrijf = LoginBedrijf.IDLoginBedrijf
1
  • 1
    I like this the best. What people are missing is you have to use the table name between DELETE AND FROM statement or use an alias you can't just have DELETE FROM Contact INNER JOIN...
    – KeyOfJ
    Jun 29, 2023 at 14:25
22

It should be:

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

You could even do a sub-query. Like this code below:

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

Try this query:

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';
2
  • 10
    I'm pretty sure a DELETE can only specify one table. This doesn't work for me. Mar 17, 2015 at 14:35
  • 7
    I believe you can specify multiple tables for deletion in mySQL, but not SQL Server (which the question asks).
    – dandev91
    Dec 20, 2016 at 5:45
8

Another way is using 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

Note: We cannot use JOIN inside CTE when you want to delete.

6

Here's what I currently use for deleting or even, updating:

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

You don't specify the tables for Company and Date, and you might want to fix that.

Standard SQL using MERGE:

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

The answer from Devart is also standard SQL, though incomplete. It should look more like this:

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

The important thing to note about the above is it is clear the delete is targeting a single table, as enforced in the second example by requiring a scalar subquery.

For me, the various proprietary syntax answers are harder to read and understand. I guess the mindset for is best described in the answer by frans eilering, i.e. the person writing the code doesn't necessarily care about the person who will read and maintain the code.

5

Delete multiple table data using transaction block, table variable and 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;

Please check from url https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=43330dda6f1b71b8ec4172a24d5b6921

Delete multiple table data with temporary table and JOIN. Drop temporary table after deletion.

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;

Please check from url https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=d52c6c1ed91669d68fcc6bc91cb32d78

Alternative way to create temporary tables by using 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;

Please check from url https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=0f02f05616ce5b4dcc8fc67c6cf1e640

Remove a single table data using 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'

Please check from url https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=84a60d1368556a8837281df36579334a

Delete single table data using 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

Please check from url https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=6590007b3c8c2ffad5563bd86606c5b1

Use ON CASCADE DELETE during foreign key creation in child table. If remove parent table data then corresponding child table data is automatically deleted.

4

Here is my SQL Server version

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

This is a simple query to delete the records from two table at a time.

DELETE table1.* ,
       table2.* 
FROM table1 
INNER JOIN table2 ON table1.id= table2.id where table1.id ='given_id'
1
  • 10
    This question is for SQL Server. You cannot delete from two tables in one statement in SQL Server. My understanding is this can be done in mysql and MS Access. Jul 10, 2018 at 21:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.