【问题标题】:Deleting duplicates in a time series删除时间序列中的重复项
【发布时间】:2015-05-31 22:31:06
【问题描述】:

我在 SQL Server 2012 表中每 1 毫秒进行一次测量。每当某些行中有 3 个或更多重复值时,我想删除中间重复项。此示例数据图像中突出显示的值是我要删除的值。有没有办法通过 SQL 查询来做到这一点?

【问题讨论】:

  • 您能告诉我们 SQL Server 的版本吗?这告诉我们窗口函数是否是一个选项
  • 它在问题中说 SQL 2012。我很想看看它们是如何工作的(我从未使用过它们)。
  • 服务器版本为2012 Express。
  • 您真的想删除它们还是只是将重复测量的范围压缩到最小和最大观察时间?我不是科学家,但删除数据似乎是个坏主意。
  • 是的,我想删除重复的中间值。画一条线只需要点——中间的额外点没有任何价值。

标签: sql-server duplicates time-series sql-delete


【解决方案1】:

您可以使用CTEROW_NUMBER 来做到这一点:

SQL Fiddle

WITH CteGroup AS(
    SELECT *,
        grp = ROW_NUMBER() OVER(ORDER BY MS) - ROW_NUMBER() OVER(PARTITION BY Value ORDER BY MS)
    FROM YourTable
),
CteFinal AS(
    SELECT *,
        RN_FIRST = ROW_NUMBER() OVER(PARTITION BY grp, Value ORDER BY MS),
        RN_LAST  = ROW_NUMBER() OVER(PARTITION BY grp, Value ORDER BY MS DESC)
    FROM CteGroup
)
DELETE 
FROM CteFinal 
WHERE
    RN_FIRST > 1
    AND RN_LAST > 1 

【讨论】:

  • 这几乎可以工作。但是,如果一个数据点之前和之后是相等的值,它将被删除。例如,20,20,40,20,20 - 40 在不应该删除时被删除。我尝试将 where 子句更改为“LG=LD 和 LG=Value”,但这似乎无法正常工作。
  • 我怀疑这里应该是WHERE RN_FIRST <> 1 AND RN_LAST <> 1
  • @GiorgiNakeuri,我相信> 就足够了,因为ROW_NUMBER1 开始,还是我错过了什么?
  • @wewestthemenace,是的,它是一样的,因为 rns 是正数。对不起。
  • 看起来现在可以完美运行了。您能否解释一下如何或为我指出一个了解 CTE 和分区的好地方?谢谢!
【解决方案2】:

我确信必须有一种更有效的方法来执行此操作,但您可以将表连接到自身两次以查找列表中的上一个和下一个值,然后删除所有三个值都存在的所有条目一样的。

DELETE FROM tbl
WHERE ms IN
(
  SELECT T.ms
  FROM tbl T
  INNER JOIN tbl T1 ON T.ms = T1.ms + 1
  INNER JOIN tbl T2 ON T.ms = T2.ms - 1
  WHERE T.value = T1.value AND T.value = T2.value
)

如果表真的很大,我可以看到这个正在吹的 tempdb。

【讨论】:

    【解决方案3】:

    是的,有

     select * from table group by table.field ->value
    

    【讨论】:

    • 这不考虑值的顺序。
    猜你喜欢
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2021-07-21
    • 2019-10-19
    • 2021-04-08
    • 1970-01-01
    • 2021-02-25
    • 2016-01-19
    相关资源
    最近更新 更多