Sql 从满足条件的第一行删除15分钟内的行

Sql 从满足条件的第一行删除15分钟内的行,sql,database,postgresql,window-functions,group-by,Sql,Database,Postgresql,Window Functions,Group By,我有这样的数据 Name | Date | Event | Event_ID _____________________________________________________________ BRADLEY | 2014-12-01 16:15:26.442 | ACCESSED | 268766 BRADLEY | 2014-12-01 16:15:36.794 | ACCESSED | 268

我有这样的数据

Name     |  Date                     |  Event     |  Event_ID
_____________________________________________________________
BRADLEY  |  2014-12-01 16:15:26.442  |  ACCESSED  |  268766  
BRADLEY  |  2014-12-01 16:15:36.794  |  ACCESSED  |  268766  
BRADLEY  |  2014-12-01 16:15:50.618  |  DENIED    |  268766  
BRADLEY  |  2014-12-01 16:16:04.89   |  DENIED    |  268766  
BRADLEY  |  2014-12-01 16:18:01.036  |  DENIED    |  268766  
BRADLEY  |  2014-12-01 16:18:31.335  |  DENIED    |  268766  
CHARLES  |  2014-12-01 08:33:34.831  |  ACCESSED  |  445317  
CHARLES  |  2014-12-01 08:33:44.041  |  ACCESSED  |  445317  
CHARLES  |  2014-12-01 14:56:49.872  |  ACCESSED  |  10333360
CHARLES  |  2014-12-01 14:56:57.549  |  ACCESSED  |  10333360
CHARLES  |  2014-12-01 14:56:59.248  |  ACCESSED  |  10333360
CHARLES  |  2014-12-01 14:56:62.221  |  ACCESSED  |  10333360
CHARLES  |  2014-12-01 14:56:63.226  |  ACCESSED  |  10333360
我的要求是,我需要删除相隔15分钟内访问的
事件。例如,布拉德利,我会删除在时间戳
16:15:36.794
处访问的第二个。这一部分对我来说很简单,因为我可以在逻辑上将同一个表连接在一起,比较当前行和下一行,并在
日期
上执行逻辑

现在我遇到的问题是查尔斯。他的
10333360
事件ID
比布拉德利的用例要复杂一些。对于CHARLES,我需要删除所有
访问的
事件ID为
10333360
日期为
14:56:49.872的
之外。这是因为我需要删除新的
事件\u ID
开始时15分钟内的所有日期。现实世界的问题是,当用户被
访问时,会有太多的“重复项”,而我正在进行数据清理以删除所有这些不必要的
访问的
数据

我曾想过在Postgres中使用窗口函数,但似乎没有任何东西可以帮助我比较日期的逻辑()


对于如何使用存储过程和创建临时表来解决这个问题,我有一些想法,这样我就可以以类似Java的方式实际使用变量。但是我当然希望它是高效的,我希望学习如何解决这样的问题的新技术。

这很棘手,因为哪些行被删除,哪些行保留取决于表的其余部分。所以你有一个移动的目标。为了把鸡拴住,我建议你应用一个网格(在你的情况下为15分钟):

现在,删除
很简单:

DELETE FROM tbl t
USING (<above query>) x
WHERE  t.tbl_id = x.tbl_id
AND    x.rn > 1;
从tbl t中删除
使用(


旁白:不要将时间戳称为“日期”,这是误导性的。

Wow,这是一种解决方案。目前正在测试它,但有一个问题,即“generate\u series”(注意,最大值,间隔“15分钟”)是否存在语法错误g'?@cYn:您需要Postgres 9.3或更高版本。由于您没有指定,我自然假设当前版本为Postgres。啊,等等,没关系。generate_系列正与其上方嵌套的selected语句连接。两个“g”别名让我有点困惑。@cYn:我为分区添加了缺少的事件_id,为旧版本添加了一个变量没有横向的版本。简直太棒了。你的代码很好用。现在我只需要把它梳理一下,这样我就可以理解它并把它放到我的工具箱里。谢谢你。
   FROM  (SELECT generate_series(min(date)
                               , max(date)
                               , interval '15 min') g
          FROM tbl WHERE event = 'ACCESSED') g
DELETE FROM tbl t
USING (<above query>) x
WHERE  t.tbl_id = x.tbl_id
AND    x.rn > 1;