我在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')
没有删除的选择正常。它返回所有不在左表中且比2010年早的行。
我收到了这个错误:
Msg 116,Level 16,State 1,Line
当未使用EXISTS引入子查询时,只能在选择列表中指定一个表达式。
答案 0 :(得分:2)
当您使用IN
运算符时,子查询必须返回一个列/值,这意味着您无法使用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'
)
此外,使用top
没有任何order by
子句会给您一个随机结果 - top
应始终与order by
子句一起使用。
答案 1 :(得分:2)
嗯,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')
您的查询不会执行此操作:
没有删除的选择正常。它返回所有的行 不在左表中且比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
的位置。您的问题没有提及。
答案 2 :(得分:1)
您也可以使用不存在条款,
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
);