Я хочу удалить с помощью INNER JOIN в SQL Server 2008 .

Но я получаю такую ​​ошибку:

Сообщение 156, уровень 15, состояние 1, строка 15
Неправильный синтаксис рядом с ключевым словом "INNER".

Мой код:

DELETE 
FROM WorkRecord2 
INNER JOIN Employee 
        ON EmployeeRun=EmployeeNo
WHERE Company = '1' 
    AND Date = '2013-05-06'
1629
nettoon493 10 Май 2013 в 15:38
3
Пример C в документации показывает, как использовать DELETE с присоединением
 – 
Pondlife
10 Май 2013 в 18:22
5
Пример C использует курсор и кучу посторонних вещей
 – 
reggaeguitar
28 Янв 2020 в 01:45
2
Пример D Использование соединений и подзапросов к данным в одной таблице для удаления строк в другой таблице может быть правильным.
 – 
fish-404
18 Янв 2022 в 08:42

16 ответов

Лучший ответ

Вам необходимо указать, из какой таблицы вы удаляете. Вот версия с псевдонимом:

DELETE w
FROM WorkRecord2 w
INNER JOIN Employee e
  ON EmployeeRun=EmployeeNo
WHERE Company = '1' AND Date = '2013-05-06'
2800
Peter Mortensen 16 Янв 2021 в 04:00
9
Не могли бы вы предоставить правильный синтаксис SQL Server для удаления из обеих таблиц?
 – 
oabarca
21 Май 2014 в 18:43
58
В SQL Server для удаления из 2 таблиц необходимо использовать 2 отдельных оператора.
 – 
Taryn
27 Май 2014 в 18:12
10
В SQL Server вы можете использовать транзакции и псевдотаблицы, как показано в stackoverflow.com/questions/783726/…
 – 
Mathieu Rodic
2 Июн 2014 в 00:28
3
Спасибо, что поделился. В моей настройке, если я удалю из двух таблиц отдельно, я действительно больше не знаю, какие строки удалить из второй таблицы, так что это поможет :)
 – 
Verena Haunschmid
24 Авг 2016 в 08:56
2
Это псевдоним для таблицы WorkRecord2.
 – 
Taryn
29 Апр 2018 в 18:57
 DELETE a FROM WorkRecord2 a 
       INNER JOIN Employee b 
       ON a.EmployeeRun = b.EmployeeNo 
       Where a.Company = '1' 
       AND a.Date = '2013-05-06'
11
Khurram Ali 29 Апр 2015 в 20:19

Эта версия должна работать:

DELETE WorkRecord2
FROM WorkRecord2 
INNER JOIN Employee ON EmployeeRun=EmployeeNo
Where Company = '1' AND Date = '2013-05-06'
13
Peter Mortensen 16 Янв 2021 в 04:06

Попробуйте этот запрос:

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';
9
Peter Mortensen 16 Янв 2021 в 04:06
9
Я почти уверен, что DELETE может указывать только одну таблицу. У меня это не работает.
 – 
Stealth Rabbi
17 Мар 2015 в 17:35
4
Я считаю, что вы можете указать несколько таблиц для удаления в mySQL, но не в SQL Server (что задается вопросом).
 – 
dandev91
20 Дек 2016 в 08:45

Другой способ - использовать 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

Примечание. Мы не можем использовать JOIN внутри CTE, когда вы хотите delete.

8
Peter Mortensen 16 Янв 2021 в 04:24

Просто добавьте имя таблицы между DELETE и FROM, откуда вы хотите удалить записи, потому что мы должны указать таблицу для удаления. Также удалите предложение ORDER BY, потому что при удалении записей нечего упорядочивать.

Итак, ваш окончательный запрос должен быть таким:

    DELETE WorkRecord2 
      FROM WorkRecord2 
INNER JOIN Employee 
        ON EmployeeRun=EmployeeNo
     WHERE Company = '1' 
       AND Date = '2013-05-06';
198
Peter Mortensen 16 Янв 2021 в 04:03
4
Этот работает на SQL Server, если вы собираетесь удалить только из первой таблицы.
 – 
TroySteven
21 Дек 2018 в 21:55
2
@matwonk: Вы можете удалить из второй таблицы, если используете имя второй таблицы. Например. использование DELETE Employee удалит из таблицы Сотрудника вместо таблицы WorkRecord2.
 – 
Himanshu
22 Дек 2018 в 07:18
2
 – 
Himanshu
2 Май 2019 в 13:52
1
Порядок удаления может иметь значение, если вы удаляете из таблицы, которая сама является внешним ключом (и не используете каскадное удаление). Но я согласен, в целом, это не имеет значения ...
 – 
Daniel
8 Апр 2021 в 23:57

Возможно, это будет вам полезно -

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 ....
)
36
Peter Mortensen 16 Янв 2021 в 04:03
2
Это единственный ответ, который работает на Sql Server. Просто создайте свой запрос, например, выберите идентификатор из ... присоединиться ... присоединиться и т.д., затем оберните его как подзапрос и выполните удаление из (таблица), где идентификатор в (подзапрос)
 – 
Chris Moschini
29 Сен 2015 в 17:18
3
Это один из многих ответов, которые работают на SQL Server. Я предлагаю принятый ответ как лучший способ сделать это.
 – 
Geoff Griswald
5 Окт 2020 в 16:19

Попробуй это:

DELETE FROM WorkRecord2 
       FROM Employee 
Where EmployeeRun=EmployeeNo
      And Company = '1' 
      AND Date = '2013-05-06'
31
Behrouz Bakhtiari 10 Май 2013 в 21:37

Должен быть:

DELETE zpost 
FROM zpost 
INNER JOIN zcomment ON (zpost.zpostid = zcomment.zpostid)
WHERE zcomment.icomment = "first"       
19
Tony Stark 17 Сен 2014 в 17:12

В 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:

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
18
Peter Mortensen 16 Янв 2021 в 04:10

Вы не указываете таблицы для Company и 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;

Ответ от Devart также является стандартным SQL, хотя и неполным. Это должно выглядеть примерно так:

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

Важно отметить вышесказанное: очевидно, что удаление нацелено на одну таблицу, как это предусмотрено во втором примере, требуя скалярного подзапроса.

Мне труднее читать и понимать ответы на различные проприетарные синтаксисы. Думаю, образ мышления лучше всего описать в ответ Франса Эйлеринга, т.е. человек, пишущий код, не обязательно заботится о человеке, который будет читать и поддерживать код.

5
Peter Mortensen 16 Янв 2021 в 04:19

Вот моя версия 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
Andy 9 Мар 2016 в 12:28

Это простой запрос для удаления записей из двух таблиц за раз.

DELETE table1.* ,
       table2.* 
FROM table1 
INNER JOIN table2 ON table1.id= table2.id where table1.id ='given_id'
6
Peter Mortensen 21 Янв 2021 в 09:29
10
Это вопрос к SQL Server. Вы не можете удалить из двух таблиц в одном операторе SQL Server. Насколько я понимаю, это можно сделать в MySQL и MS Access.
 – 
Darren Griffith
11 Июл 2018 в 00:43

Вы даже можете сделать подзапрос. Как этот код ниже:

DELETE FROM users WHERE id IN(
    SELECT user_id FROM Employee WHERE Company = '1' AND Date = '2013-05-06'
)
7
Peter Mortensen 16 Янв 2021 в 04:30

Вот что я сейчас использую для удаления или даже обновления:

DELETE           w
FROM             WorkRecord2   w,
                 Employee      e
WHERE            w.EmployeeRun = e.EmployeeNo
             AND w.Company = '1' 
             AND w.Date = '2013-05-06'
6
PPJN 11 Окт 2019 в 22:41

Удалите несколько табличных данных, используя блок транзакции, табличную переменную и 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;

Пожалуйста, проверьте по URL-адресу https://dbfiddle.uk/4&rdbd24e4d06e4e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6

Удалите несколько данных таблицы с помощью временной таблицы и 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;

Пожалуйста, проверьте по URL-адресу https://dbfiddle.uk/16fserc78cdl2dl6ddd06d6d6d6d6d06d6d6d6e6d6e6fdddddddddddddddddddddddddddddddddd2

Альтернативный способ создания временных таблиц с помощью 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;

Пожалуйста, проверьте по URL-адресу https://dbfiddle.uk6fc6e6e0c8cf0cf0c8cf0c6f0cf0cf0c6f0cf0cf0cf0cf0cf0c6f0cf0cf0cf0cf0cf0cf0cf0cf0cf0cf0cf0cf0cf0cf0cfd0cf0,

Удалите данные одной таблицы с помощью 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=14&alserver_ru/?rdbms=sqalserver_ru/?rdbms=14&Alserver_08983

Удалить данные одной таблицы с помощью 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

Пожалуйста, проверьте по URL-адресу https://dbfiddle.uk/cfd86606c5d06e6d06e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e5

Используйте ON CASCADE DELETE во время создания внешнего ключа в дочерней таблице. При удалении данных родительской таблицы соответствующие данные дочерней таблицы удаляются автоматически.

3
Rahul Biswas 3 Окт 2021 в 17:07