如何删除连续的类似行并仅保留最近的行?

时间:2017-10-10 16:53:02

标签: sql sql-server distinct

我有这张桌子

the source

我想删除连续的类似行并保留最近的行。 所以我想要的结果是这样的

the result

2 个答案:

答案 0 :(得分:0)

我将如何做到这一点:

;WITH cte AS (
    SELECT valeur, date_reference, id, rownum = ROW_NUMBER() OVER (ORDER BY date_reference) FROM #temperatures
    UNION ALL
    SELECT NULL, NULL, NULL, (SELECT COUNT(*) FROM #temperatures) + 1
)
SELECT A.* FROM cte AS A INNER JOIN cte AS B ON A.rownum + 1 = B.rownum AND COALESCE(a.valeur, -459) != COALESCE(b.valeur, -459)

我正在调用表#temperatures。使用CTE为每条记录分配ROW_NUMBER并包含最后一条Row_Number的额外记录(否则最后一条记录将不包含在以下查询中)。然后,来自CTE的SELECT,其中下一个ROW_NUMBER没有相同的valeur

现在,如果您想要从原始表中DELETE,您可以查看此查询的返回,以确保您确实要删除此返回中不包含的所有记录。然后,假设historique_id是主键DELETE FROM #temperatures WHERE historique_id NOT IN (SELECT historique_id FROM cte AS A...

答案 1 :(得分:0)

您可以收集要保存在临时表中的所有行,truncate原始表,并将临时表中的所有行插入到原始表中。这比仅仅删除行更有效,以防你有很多重复"。 truncate table也有以下限制

您不能在以下表格上使用TRUNCATE TABLE:

  1. 由FOREIGN KEY约束引用。 (你可以截断一个 具有引用自身的外键的表。)
  2. 参与索引视图。
  3. 使用事务复制或合并发布 复制。
  4. TRUNCATE TABLE无法激活触发器,因为操作有效 不记录单个行删除。有关详细信息,请参阅CREATE TRIGGER (Transact-SQL)
  5. 在Azure SQL数据仓库和并行数据仓库中:

    1. EXPLAIN语句中不允许使用TRUNCATE TABLE。
    2. 无法在事务内部运行TRUNCATE TABLE。
    3. 您可以在以下主题中找到更多信息。

      Truncate in SQL SERVER

      Deleting Data in SQL Server with TRUNCATE vs DELETE commands

      您可以使用此脚本通过truncate-insert策略删除重复行

       CREATE TABLE #temp_hisorique(
      code varchar(50),
      code_trim varchar(50),
      libelle varchar(50),
      unite varchar(50),
      valeur varchar(50),
      date_reference datetime,
      hisoriqueID int
      )
      GO
      ;WITH cte AS (
          select *, row_number() over(partition by code, code_trim, libelle, unite, valeur order by date_reference desc) as rownum
          from mytable
      )
      
      insert into #temp_hisorique(code, code_trim, libelle, unite, valeur, date_reference, hisoriqueID)
      select code, code_trim, libelle, unite, valeur, date_reference, hisoriqueID
      from cte
      where rownum = 1
      
      TRUNCATE TABLE mytable
      
      insert into mytable(code, code_trim, libelle, unite, valeur, date_reference, hisoriqueID)
      select code, code_trim, libelle, unite, valeur, date_reference, hisoriqueID
      from #temp_hisorique
      

      或者你可以通过delete命令删除行。

      ;WITH cte AS (
          select *, row_number() over(partition by code, code_trim, libelle, unite, valeur order by date_reference desc) as rownum
          from mytable
      )
      
      delete  T
      from mytable T
      join cte on T.hisoriqueID = cte.hisoriqueID
      where cte.rownum > 1