Как удалить с помощью INNER JOIN с SQL Server?

1283

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

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

Сообщение 156, уровень 15, состояние 1, строка 15
Неверный синтаксис рядом с ключевым словом «ВНУТРЕННИЙ».

Мой код:

DELETE FROM WorkRecord2 
INNER JOIN Employee ON EmployeeRun=EmployeeNo
WHERE Company = '1' AND Date = '2013-05-06'
nettoon493
источник
2
Пример C в документации показывает, как использовать DELETEс объединением
Pondlife
1
В примере C используется курсор и куча посторонних вещей
reggaeguitar
Удалить из таблицы1 из таблицы1 t1 внутреннего соединения таблицы2 t2 на t1.id = t2.id; подробнее youtu.be/_tyUVrS2iH4
Амреш Кумар Сингх

Ответы:

2244

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

DELETE w
FROM WorkRecord2 w
INNER JOIN Employee e
  ON EmployeeRun=EmployeeNo
WHERE Company = '1' AND Date = '2013-05-06'
Тарын
источник
9
@bluefeet Не могли бы вы предоставить правильный синтаксис для SQL Server для удаления из обеих таблиц?
oabarca
44
@ user2070775 В SQL Server для удаления из 2 таблиц необходимо использовать 2 отдельных оператора.
Тарын
8
@ user2070775 в SQL Server вы можете использовать транзакции и псевдотаблицы, как показано в stackoverflow.com/questions/783726/…
Матье Родик
1
@MathieuRodic спасибо, что поделились. В моей настройке, если я удаляю из 2 таблиц отдельно, я больше не знаю, какие строки удалять из 2-й таблицы, так что это поможет :)
Verena Haunschmid
2
@ShahryarSaljoughi, который является псевдонимом для таблицы WorkRecord2.
Тарын
152

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

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

    DELETE WorkRecord2 
      FROM WorkRecord2 
INNER JOIN Employee 
        ON EmployeeRun=EmployeeNo
     WHERE Company = '1' 
       AND Date = '2013-05-06';
hims056
источник
3
Этот работает на SQL Server, если вы собираетесь удалить только из первой таблицы.
TroySteven
1
@matwonk: Вы можете удалить из второй таблицы, если вы используете имя второй таблицы. Например, использование DELETE Employeeудалит из таблицы Сотрудника вместо WorkRecord2таблицы.
hims056
30

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

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 ....
)
Devart
источник
1
Это единственный ответ, который работает на Sql Server. Просто создайте свой запрос, как select Id from ... join ... join и т. Д., Затем оберните его как подзапрос и выполните удаление из (таблицы), где Id in (подзапрос)
Chris Moschini
28

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

DELETE FROM WorkRecord2 
       FROM Employee 
Where EmployeeRun=EmployeeNo
      And Company = '1' 
      AND Date = '2013-05-06'
Бехруз Бахтиари
источник
16

Должен быть:

DELETE zpost 
FROM zpost 
INNER JOIN zcomment ON (zpost.zpostid = zcomment.zpostid)
WHERE zcomment.icomment = "first"       
йогинер багга
источник
11

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

DELETE WorkRecord2
FROM WorkRecord2 
INNER JOIN Employee ON EmployeeRun=EmployeeNo
Where Company = '1' AND Date = '2013-05-06'
AustinTX
источник
11

В 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
Франс Айлинг
источник
10
 DELETE a FROM WorkRecord2 a 
       INNER JOIN Employee b 
       ON a.EmployeeRun = b.EmployeeNo 
       Where a.Company = '1' 
       AND a.Date = '2013-05-06'
Дханрадж Миттал
источник
9

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

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';
Али
источник
8
Я уверен, что DELETE может указывать только одну таблицу. Это не работает для меня.
Раввин Стелс
3
Я считаю, что вы можете указать несколько таблиц для удаления в MySQL, но не SQL Server (который задает вопрос).
dandev91
7

Еще один способ использования 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.

P ரதீப்
источник
6

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

DELETE table1.* ,
       table2.* 
FROM table1 
INNER JOIN table2 ON table1.id= table2.id where table1.id ='given_id'
Ади
источник
2
Этот вопрос для SQL Server. Вы не можете удалить из двух таблиц в одной инструкции в SQL Server. Насколько я понимаю, это можно сделать в MySQL и MS Access.
Даррен Гриффит
6

Попробуйте это, это может помочь

 DELETE WorkRecord2 
          FROM WorkRecord2 
    INNER JOIN Employee 
            ON EmployeeRun=EmployeeNo
         WHERE Company = '1' 
           AND Date = '2013-05-06';
Вирадж Шарма
источник
7
Чем он отличается от принятого ответа: stackoverflow.com/questions/16481379/… ?
локаль по умолчанию
3
В этом ответе используется явное именование таблиц, а не псевдонимы, что делает его более понятным для тех, кто менее опытен, для чтения / понимания происходящего.
Джошуа Бернс
1
@JoshuaBurns: все еще точная копия моего ответа .
hims056
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)
ozzy432836
источник
4

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

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

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

onedaywhen
источник
4

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

DELETE           w
FROM             WorkRecord2   w,
                 Employee      e
WHERE            w.EmployeeRun = e.EmployeeNo
             AND w.Company = '1' 
             AND w.Date = '2013-05-06'
PPJN
источник