我想不出一个很好的标题。我有一个自动化仓库,里面有输送机移动箱子。每个盒子都有一个唯一的包裹编号。有数十个扫描仪告诉盒子要去的地方。扫描仪每次看到一个框时,都会在表中创建两行(排序和确认),如下所示:
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需要多长时间?也许最好再提第二个问题。谢谢!
答案 0 :(得分:1)
SELECT parcel, passed_scanners
FROM (
SELECT
parcel,
array_agg(scanner) as passed_scanners
FROM
scanners
GROUP BY parcel
)s
WHERE 's15' = ANY(passed_scanners) AND NOT (ARRAY['s71', 's72'] && passed_scanners)
scanner_id
passed_scanners
两个数组的运算符)的地块行,检查两个数组是否都包含数组元素-称为 array overlay )第二部分是一个不同的查询,因为在第一部分中,您要求仍未到达最终扫描仪的包裹。在第二部分中,您要计算最终到达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的地块行 请注意:如果您的包裹在午夜扫描,passed_scanners
列中没有任何日期成分,则持续时间的结果可能不起作用。然后,您可能会在s15开始于23h,而目的地将在1h。时差为time
。为了解决这个问题,我强烈建议您保存带有日期部分的整个时间戳。
否则,您必须检查:如果(1 - 23) = -22
然后增加24小时(但是如果包裹需要超过24小时又该怎么办?如何知道您不需要增加48小时呢?)