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;