Postgresql 用Postgres在自动化日志中倾注

Postgresql 用Postgres在自动化日志中倾注,postgresql,Postgresql,我想不出一个好题目来回答我的问题。我有一个自动仓库,有传送带搬运箱子。每个箱子都有一个唯一的包裹编号。有几十台扫描仪告诉箱子去哪里。每次扫描仪看到一个框时,它都会在表中创建两行(排序和确认),如下所示: time scanner type parcel 12:00:19.635 s15 Sort 83128 12:00:20.3 s15 Confirm 83128 12:02:05.857

我想不出一个好题目来回答我的问题。我有一个自动仓库,有传送带搬运箱子。每个箱子都有一个唯一的包裹编号。有几十台扫描仪告诉箱子去哪里。每次扫描仪看到一个框时,它都会在表中创建两行(排序和确认),如下所示:

    time          scanner    type    parcel
12:00:19.635        s15      Sort     83128
12:00:20.3          s15      Confirm  83128
12:02:05.857        s18      Sort     94387 
12:02:07.692        s18      Confirm  94387
因此,每个唯一的地块编号和每个唯一的扫描仪都有许多条目。我如何编写一个查询,告诉我哪些包裹已经开始旅行(见s15),但尚未到达中间部分(见s71或s72)?我也在考虑期限;盒子从s15到s71需要多长时间?或者,这最好留给第二个问题。谢谢

  • 为每个包裹聚合所有通过的
    scanner\u id
    s
  • 过滤在
    已通过的#扫描器中包含#15但既不包含#71也不包含#72的所有地块行(
    &&
    两个数组的运算符检查两个数组是否包含数组元素-称为数组重叠)

  • 第二部分是一个不同的查询,因为在第一部分中,您请求仍未到达最终扫描仪的包裹。在第二部分中,您需要计算最终到达s71的所有地块的持续时间

    SELECT parcel, duration
    FROM (
        SELECT
            parcel,
            MAX(time) FILTER (WHERE scanner IN ('s71', 's72')) -
            MIN(time) FILTER (WHERE scanner = 's15') AS duration,
            array_agg(scanner) as passed_scanners
        FROM
            scanners
        GROUP BY parcel
    )s
    WHERE 's15' = ANY(passed_scanners) AND (ARRAY['s71', 's72'] && passed_scanners)
    
  • 再次为每个包裹聚合所有通过的扫描仪ID
  • 给出扫描仪15的第一次时间和扫描仪71或72的最后一次时间。构建差异以获得持续时间
  • 已通过的#扫描器
    中过滤包含#15以及#71或#72的所有地块行
  • 请注意:如果在
    时间
    列中没有任何日期组件,则如果在午夜扫描包裹,持续时间的结果可能不起作用。那么,s15的起点可能是23小时,终点可能是1小时。时差为
    (1-23)=-22
    。为了解决这个问题,我强烈建议用日期部分保存整个时间戳


    否则,您必须检查:如果
    持续时间<0
    则添加24小时(但如果包裹需要超过24小时怎么办?如何知道您不需要添加48小时?

    这是基于
    确认
    记录还是
    排序
    记录?扫描仪编号是否按编号排序?首先是s15然后是s16然后。。。s71。我的想法是“查找扫描仪编号<71的所有行”。我一直基于排序进行查询,但我认为两者都可以。不幸的是,扫描仪编号中存在许多空白,有时它们会出现顺序错误。盒子在看到s71之前会先看到扫描仪80。但这是一个有趣的想法。好吧,所以应该检查15是通过,但不是71/72?更新了我的答案。@Tuffgong用持续时间计算更新了答案。这是您所期望的吗(那么请不要忘记接受/投票)?编辑:简化查询。无需将扫描器ID转换为具有附加要求的纯整数。哇!这看起来不错。它可能是完美的!有很多东西需要倾注,但至少我认为如果我还没有到达那里,我可以通过一些特威克来达到我需要去的地方。我真的很感激。非常感谢。
    SELECT parcel, duration
    FROM (
        SELECT
            parcel,
            MAX(time) FILTER (WHERE scanner IN ('s71', 's72')) -
            MIN(time) FILTER (WHERE scanner = 's15') AS duration,
            array_agg(scanner) as passed_scanners
        FROM
            scanners
        GROUP BY parcel
    )s
    WHERE 's15' = ANY(passed_scanners) AND (ARRAY['s71', 's72'] && passed_scanners)