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)
已通过的#扫描器
中过滤包含#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)