SQL 从左联接中删除 SELECT

SQL DELETE FROM LEFT JOIN SELECT

我在 SQL Server 2012

中有这个查询
DELETE FROM [DB1].[dbo].[Newsletter] 
WHERE [DB1].[dbo].[Newsletter].RecordID IN
            (SELECT TOP(100) *
             FROM [DB1].[dbo].[Newsletter] 
             LEFT JOIN [DB1].[dbo].[Newsletter_Tracking] ON RecordId = Newsletter_Tracking.UserId
             WHERE Newsletter.DateSubscribed < '2010-01-01')

没有删除的select可以正常工作。它 returns 所有不在左侧 table 且早于 2010 年的行。

我得到这个错误:

Msg 116, Level 16, State 1, Line
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

当您使用 IN 运算符时,子查询必须 return 一个 column/value 这意味着您不能使用 select *.

您的情况很可能是:

DELETE FROM [DB1].[dbo].[Newsletter] 
WHERE [DB1].[dbo].[Newsletter].RecordID IN (
  SELECT [DB1].[dbo].[Newsletter].RecordID
  FROM [DB1].[dbo].[Newsletter] 
  LEFT JOIN [DB1].[dbo].[Newsletter_Tracking] ON RecordId = Newsletter_Tracking.UserId
  WHERE Newsletter.DateSubscribed<'2010-01-01'
)

此外,使用不带任何 order by 子句的 top 会给您一个随机结果 - top 应始终与 order by 子句结合使用。

嗯,你需要RecordIdSELECTIN 列表只识别单一值,因此 SELECT * 通常不起作用。

DELETE FROM [DB1].[dbo].[Newsletter] 
WHERE [DB1].[dbo].[Newsletter].RecordID IN
(SELECT TOP(100) RecordId
  FROM [DB1].[dbo].[Newsletter] LEFT JOIN [DB1].[dbo].[Newsletter_Tracking]
  ON RecordId=Newsletter_Tracking.UserId
  WHERE Newsletter.DateSubscribed<'2010-01-01')

您的查询不这样做:

The select without the delete works ok. It returns all the rows which are not in left table and which are older than 2010.

但我怀疑您想要更像这样的东西:

DELETE n
    FROM [DB1].[dbo].Newsletter n
    WHERE n.DateSubscribed < '2010-01-01' AND
          n.RecordID NOT IN (SELECT nt.UserId
                             FROM [dbo].[Newsletter_Tracking] nt
                            );

我不确定 TOP 100 是从哪里来的。你的问题没有提到它。

您也可以使用 NOT EXISTS 子句,

DELETE n
    FROM [DB1].[dbo].Newsletter n
    WHERE n.DateSubscribed < '2010-01-01' AND
         NOT EXISTS (SELECT nt.UserId
                             FROM [dbo].[Newsletter_Tracking] nt.UserId= n.RecordID
                            );