【问题标题】:How to delete by row number in SQLSQL中如何按行号删除
【发布时间】:2017-10-06 18:51:35
【问题描述】:

我需要从第 475 行到第 948 行删除,因为它们与第 1-474 行重复。我猜应该是差不多的,还是还有更多?

DELETE FROM dbo.industry WHERE row_number between 475 and 948

【问题讨论】:

  • 您是否有主键,例如数据库中的 ID?如果你这样做了,你可以很容易地通过 ID 删除。
  • row_number 是您表中的一列吗?该列中的值 475-948 是您要删除的行吗?
  • @TimWilcox:嗯,添加一列很容易,但这真的是你想要的吗?你如何定义“行号”?您如何识别要删除的记录?
  • @TimWilcox:嗯,要记住的重要一点是,您所称的“行号”完全取决于您的排序方式 i> 数据。 SQL 本身并不能真正保证这一点。它通常按主键排序,但不一定必须如此。记录本身没有“行号”。
  • @TimWilcox:我认为下面的一些答案会有所帮助,但首先您必须能够确定要删除的内容。这些行不会按任何默认值排序,如果 PK 不同,它们也不会技术上重复。在技​​术、逻辑层面,在查看数据时,您能否定义一些表达式来标识要删除的行?或者,相反,要保留的行?如果是前者,那就是你的DELETE 声明。如果是后者,那是您在下面 Belgo 答案开头的 SELECT 声明。

标签: ssms sql-delete


【解决方案1】:

可能为时已晚,但我通常这样做

; with cte(rownum)as(
    select row_number () over(partition by [Col1], [Col2] order by Col3) from [table]
)
delete from cte where rownum > 1

【讨论】:

  • 我只需要做一些类似的事情,这个就完成了!
【解决方案2】:
DELETE FROM dbo.industry
WHERE COLUMN_NAME IN      -- Choose a column name
  (SELECT TOP 1000
     COLUMN_NAME,          -- Choose a column name
     ROW_NUMBER() OVER( ORDER by COLUMN_NAME ASC) AS Row_Number
   FROM dbo.industry
   WHERE Row_Number BETWEEN 475 AND 948 )

COLUMN_NAME 可以是您想要的表的任何列名。

【讨论】:

    【解决方案3】:

    如果您尝试使用Row_Number 函数删除,则会收到错误

    窗口函数只能出现在 SELECT 或 ORDER BY 子句中

    您可以修改 SQL 使其包含在 select 子句中,如下例所示:

    Delete T 
    From (Select Row_Number() Over(Partition By [IndustryType], [IndustryDescription] order By [ID]) As RowNumber,* 
    From dbo.industry) T
    Where T.RowNumber > 1
    

    【讨论】:

    • Select Row_Number() Over(Partition By [IndustryType], [IndustryDescription] order By [ID]) As RowNumber,* From dbo.industry 在 Snowflake 和 mySQL 中为我抛出错误,而 Select *, Row_Number() Over(Partition By [IndustryType], [IndustryDescription] order By [ID]) As RowNumber From dbo.industry 有效。奇怪!
    【解决方案4】:
    ALTER TABLE dbo.industryADD COLUMN tmpRowNumber COUNTER
    DELETE * FROM dbo.industry WHERE tmpRowNumber IS BETWEEN 475 AND 948
    ALTER TABLE dbo.industry DROP COLUMN tmpRowNumber
    

    但请注意,您的 DBS 可能不会将第 1 行视为第 1 行,因为表未排序

    【讨论】:

      【解决方案5】:
      SELECT DISTINCT *
      INTO #Temp
      FROM dbo.industry
      
      DELETE FROM dbo.industry
      
      INSERT INTO dbo.industry
      SELECT *
      FROM #Temp
      

      【讨论】:

      • 在 OP 上面的 cmets 中表示该表有一个主键。所以这行不通。每条记录都会被重新插入。
      • 同意,但这种可能的方法可以很容易地调整以考虑到这一点。关键是找到不同的值并重新创建它可能比搞乱行号匹配更有意义。
      • 这正是问题所在......如何定位“不同”记录。删除它们的行为不是问题。这是一个很好的尝试,但本质上你是在挥手解决实际问题。
      【解决方案6】:
      DELETE FROM dbo.industry WHERE dbo.industry.
      REPLACE WITH PK COLUMN NAME| IN (SELECT TOP 948 dbo.industry
      REPLACE WITH  PK COLUMN NAME| FROM dbo.industry WHERE dbo.industry
      REPLACE WITH  PK COLUMN NAME| > 475 ORDER BY dbo.industry 
      REPLACE WITH  PK COLUMN NAME|)
      

      【讨论】:

        【解决方案7】:

        这不是一个真正的答案。数据存在一些问题,使得上述答案(虽然很好)无关紧要。我只是删除了表格,然后从固定宽度重新导入它。这一次,我更加小心,没有重复。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-27
          • 1970-01-01
          • 1970-01-01
          • 2014-06-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多