【问题标题】:SQL DELETE FROM LEFT JOIN SELECTSQL 从左连接选择中删除
【发布时间】:2016-11-02 00:46:18
【问题描述】:

我在 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 年的行。

我得到这个错误:

消息 116,级别 16,状态 1,线路
当子查询不使用 EXISTS 引入时,选择列表中只能指定一个表达式。

【问题讨论】:

  • SELECT TOP 100 RecordID 而不是 *.
  • 使用 EXISTS 代替错误消息提示您。

标签: sql sql-server select join sql-delete


【解决方案1】:

当您使用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 子句一起使用。

【讨论】:

    【解决方案2】:

    好吧,您需要在SELECT 中添加RecordIdIN 列表只能识别单例值,因此 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 的来源。你的问题没有提到它。

    【讨论】:

    • 我已经添加了TOP 100来限制查询,因为我做了另一个完全阻塞SQL服务器的查询。
    • 你的最后一个查询我得到这个错误:DELETE FROM [DB1].[dbo].Newsletter n
    【解决方案3】:

    您也可以使用不存在从句,

    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
                                );
    

    【讨论】:

      猜你喜欢
      • 2013-01-14
      • 1970-01-01
      • 1970-01-01
      • 2017-07-02
      • 2019-05-30
      • 2022-01-09
      • 2016-07-08
      • 2021-10-31
      • 1970-01-01
      相关资源
      最近更新 更多