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
子句结合使用。
嗯,你需要RecordId
在SELECT
。 IN
列表只识别单一值,因此 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
);
我在 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
子句结合使用。
嗯,你需要RecordId
在SELECT
。 IN
列表只识别单一值,因此 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
);