这与Compute dates and durations in mysql query类似,不同之处在于我没有可以使用的唯一ID列,并且我的样本不是开始/结束点。
作为一个有趣的实验,我将cron设置为ps aux > 'date +%Y-%m-%d_%H-%M'.txt
。我现在有大约250,000个“机器正在运行的”样本。
我想把它变成“process | cmd | start | stop”的列表。假设“开始”事件是该对存在的第一次,并且“停止”事件是它停止存在的第一个样本:没有样本“遗漏”或任何东西的可能性。
那说,进行这种转换的方式有多少,最好是使用SQL(基于我喜欢SQL,这似乎是一个很好的挑战)。假设pids不能重复,这是一项微不足道的任务(将所有内容放在表格SELECT MIN(time), MAX(time), pid GROUP BY pid
中)。但是,由于PID / cmd对重复(我检查过,有重复),我需要一个方法来执行真正的“查找所有连续段”搜索。
如果有必要,我可以采用
形式Load file0 -> oldList
ForEach fileN:
Load fileN ->newList
oldList-newList = closedN
newList-oldList = openedN
oldList=newList
但这不是SQL,也不是很有趣。谁知道,我可能最终会得到真正的SQL数据来处理这个属性。
我正在考虑的事情是,首先构建一个差异表,然后将所有关闭对象连接到所有开放状态,并在每次打开后拉近最小距离,但我想知道是否有更好的方法。
答案 0 :(得分:1)
您没有提到您正在使用的数据库。我假设您正在使用支持排名功能的数据库,因为这简化了解决方案。
解决这个问题的关键是观察。您希望为每个pid分配一个ID,以查看它是否唯一。我将假设当pid在上一个带时间戳的输出中出现 not 时,pid代表一个进程。
现在,想法是:
所以,这是行动中的查询:
select groupid, pid, min(time), max(time)
from (select t.*,
(dense_rank() over (order by time) -
row_number() over (partition by pid order by time)
) as groupid
from t
) t
group by groupid, pid
这适用于大多数数据库(SQL Server,Oracle,DB2,Postgres,Teradata等)。它在MySQL中不起作用,因为MySQL不支持窗口/分析函数。