【问题标题】:Calculate total duration using timestamp使用时间戳计算总持续时间
【发布时间】:2020-10-26 18:31:34
【问题描述】:

在我的 SQLite 表中,我有以下字段(timestampzone_idobject_countobject_ids),这些是人们在区域中排队的数据。每当有人加入队列时,他都会被传感器捕获并分配一个object_idtimestamp 是传感器服务器每秒向数据库发送的数据。

我需要找到队列中每个 object_ids 的持续时间,以使用烧瓶框架计算和显示我的 Web 应用程序中的等待时间。比如object_ids(2166)在2020-10-19 17:03:46.000000进入队列,在2020-10-19 17:03:50.000000离开,他的排队时间是5秒。简单的逻辑是从object_id 最后出现的时间戳中减去object_id 第一次出现时的时间戳。

#       timestamp           zone_id   object_count      object_ids #  

2020-10-19 17:03:43.000000    10           2         ['2140', '2143']
2020-10-19 17:03:44.000000    10           2         ['2140', '2143']
2020-10-19 17:03:45.000000    10           2         ['2140', '2143']
2020-10-19 17:03:46.000000    10           3         ['2140', '2143', '2166']
2020-10-19 17:03:47.000000    10           3         ['2140', '2143', '2166']
2020-10-19 17:03:49.000000    10           3         ['2140', '2143', '2166']
2020-10-19 17:03:50.000000    10           3         ['2140', '2143', '2166']
2020-10-19 17:03:51.000000    10           2         ['2140', '2143']
2020-10-19 17:03:53.000000    10           2         ['2140', '2143']

如何查询和解决?

【问题讨论】:

  • 你在做这个的时候遇到了什么困难?
  • @mkrieger1 我是 sqlite 语法的新手,我不确定编写它的正确方法。如果有人能指出正确的方法,将不胜感激。
  • 这里显示了正确的方法:docs.python.org/3/library/sqlite3.html
  • object_ids的数据类型是什么?
  • @forpas object_ids 的数据类型是字符串。

标签: python sqlite


【解决方案1】:

假设您的表名是 queues 并且定义了 object_ids 的表是 objects(将名称更改为实际名称),所以您有这样的内容:

CREATE table objects (`object_id` TEXT);
INSERT INTO objects (`object_id`) VALUES
  ('2140'), ('2143'), ('2166');

CREATE TABLE queues (`timestamp` TEXT, `zone_id` INTEGER, `object_count` INTEGER, `object_ids` VARCHAR(24));
INSERT INTO queues (`timestamp`, `zone_id`, `object_count`, `object_ids`) VALUES
  ('2020-10-19 17:03:43.000000', '10', '2', '[''2140'', ''2143'']'),
  ('2020-10-19 17:03:44.000000', '10', '2', '[''2140'', ''2143'']'),
  ('2020-10-19 17:03:45.000000', '10', '2', '[''2140'', ''2143'']'),
  ('2020-10-19 17:03:46.000000', '10', '3', '[''2140'', ''2143'', ''2166'']'),
  ('2020-10-19 17:03:47.000000', '10', '3', '[''2140'', ''2143'', ''2166'']'),
  ('2020-10-19 17:03:49.000000', '10', '3', '[''2140'', ''2143'', ''2166'']'),
  ('2020-10-19 17:03:50.000000', '10', '3', '[''2140'', ''2143'', ''2166'']'),
  ('2020-10-19 17:03:51.000000', '10', '2', '[''2140'', ''2143'']'),
  ('2020-10-19 17:03:53.000000', '10', '2', '[''2140'', ''2143'']');

通过使用窗口函数MIN()MAX() 以及函数strftime(),您可以使用连接两个表的SQLite 查询获得所需的结果:

SELECT DISTINCT o.object_id,
       strftime('%s', MAX(q.timestamp) OVER (PARTITION BY o.object_id)) - 
       strftime('%s', MIN(q.timestamp) OVER (PARTITION BY o.object_id)) diff
FROM objects o INNER JOIN queues q
ON ',' || REPLACE(REPLACE(REPLACE(REPLACE(q.object_ids, '''', ''), '[', ''), ']', ''), ' ', '') || ','
LIKE '%,' || o.object_id || ',%'

如果您的 SQLite 版本不支持窗口函数,请使用 GROUP BY:

SELECT o.object_id,
       strftime('%s', MAX(q.timestamp)) - strftime('%s', MIN(q.timestamp)) diff
FROM objects o INNER JOIN queues q
ON ',' || REPLACE(REPLACE(REPLACE(REPLACE(q.object_ids, '''', ''), '[', ''), ']', ''), ' ', '') || ','
LIKE '%,' || o.object_id || ',%'
GROUP BY o.object_id

请参阅demo
结果:

> object_id | diff
> :-------- | ---:
> 2140      |   10
> 2143      |   10
> 2166      |    4

【讨论】:

    【解决方案2】:

    因此,在您的 application.py 中,您应该有此代码以获取正确的数据库,这应该位于文件中的某个位置,以便您的所有函数都可以访问它。

    engine = create_engine(os.getenv("DATABASE_URL"))
    db = scoped_session(sessionmaker(bind=engine))
    

    然后在你希望有时间拥有的功能中的某个地方,你应该有这样的东西

    timestamp = db.execute(text("SELECT timestamp FROM NAME_OF_YOUR_TABLE").fetchall()#this will get you all of the timestamps
    

    现在您在 python 中获得了表格中的时间戳,因此您可以轻松地做任何您想做的事情,您可以轻松地将其转换为 datetime 格式,然后只需使用 datetime.datetime.now() 函数并减去它来自彼此,如果您还有其他需要,请随时在下面发表评论。

    编辑:所以为了遍历 IDs 列,你需要这样的东西:

    T1 = db.execute(text("SELECT object_ids FROM NAME_OF_YOUR_TABLE")).fetchall()
    for i in T1:
       
       timestamp = db.execute(text("SELECT timestamps FROM NAME_OF_YOUR_TABLE WHERE object_ids=:object_ids"), {'object_ids':i}).fetchone()
       print('Timestamp = ' + timestamp 'and id = ' + i)
    

    【讨论】:

    • 您好,感谢您的回复。我实际上需要区域中每个 object_ids 的总持续时间,因为我将在仪表板上显示队列的等待时间,并且它会自动刷新。
    • @gabgabgab93 我编辑了我的代码,所以它会得到所有的时间戳,然后你可以在 python 中循环它们
    • 嗨奥利弗,我认为我真正需要的是遍历每个“object_ids”并标记出开始和结束时间戳,以便计算每个 id 所用的时间。谢谢!
    • 好的,我的答案又改了,你现在试一试,请让我现在怎么样,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 2017-08-30
    • 2014-01-14
    • 1970-01-01
    相关资源
    最近更新 更多