Php 在PostgreSQL中查找集合之间的所有行
我有一个名为tc_fuel的表格,它接收来自GPS车辆的所有燃油相关数据,我想得到最后一个油箱的使用量,以计算整个油箱的MPG,但油箱满100时的读数在2行或3行或更多行后重复多次,因此我的两个100值相邻,我希望能够得到最后一次填充开始和结束ID 到目前为止,我所拥有的: 选择 tc_燃料设备ID, tc_燃料id, 燃料, tc_燃料。使用的燃料, 使用的燃料 从tc_燃料 其中燃料=100 和deviceid=19 按ID订购 描述限制2 然后我进入PHP,检查id差异是否超过100条记录,以检查燃油值是否彼此不相邻,但这比应该做的工作要多。我想知道是否有更好的方法 例如,这辆车从一个满油箱开始,然后下降到6%油箱,并进行满油箱加注,我希望能够获取最后一个油箱的所有数据Php 在PostgreSQL中查找集合之间的所有行,php,sql,postgresql,window-functions,gaps-and-islands,Php,Sql,Postgresql,Window Functions,Gaps And Islands,我有一个名为tc_fuel的表格,它接收来自GPS车辆的所有燃油相关数据,我想得到最后一个油箱的使用量,以计算整个油箱的MPG,但油箱满100时的读数在2行或3行或更多行后重复多次,因此我的两个100值相邻,我希望能够得到最后一次填充开始和结束ID 到目前为止,我所拥有的: 选择 tc_燃料设备ID, tc_燃料id, 燃料, tc_燃料。使用的燃料, 使用的燃料 从tc_燃料 其中燃料=100 和deviceid=19 按ID订购 描述限制2 然后我进入PHP,检查id差异是否超过100条记录
id | deviceId | fuel
------+-----------+-------
1 | 19 | 100 <-- This should be starting point
2 | 19 | 97
3 | 19 | 100
4 | 19 | 96
5 | 19 | 94
6 | 19 | .... (keeps dropping)
7 | 19 | 33
8 | 19 | 31
9 | 19 | 30
10 | 19 | ....
11 | 19 | 6
12 | 19 | 5
13 | 19 | 6 <-- This should be end point (will flag this id as processed)
14 | 19 | 100 <-- Starts all over again in next iteration of the php script
15 | 19 | 99
16 | 19 | 98
17 | 19 | 100
18 | 19 | 99
19 | 19 | 97
20 | 19 | 96
21 | 19 | ....
填充的定义有点模糊。我假设当燃料值上升超过50时,这是一次加油。替换为您选择的数字。看起来一个新的油箱必须从燃油=100开始,尽管这是一个奇怪的情况。我添加了注释-取消注释以激活: 挑选* 从…起 选择*,计数*过滤器,其中按设备填充分区\u id按id排序作为油箱 从…起 挑选* ,fuel-lagfoure,1,0超过按设备划分的分区\u id顺序按id>50 -燃油=100-附加条件? 作为补充 来自tbl sub1 sub2 其中,设备_id=19 和储罐=1; 小提琴 在子查询sub1中,计算每个设备前面的燃料条目与当前的燃料条目之间的差异-使用。值得注意的是,我使用带有3个参数的变量,为缺少的行提供0作为默认值,以覆盖每个分区的第一行。增加超过50表示新的填充 在子查询sub2中,使用另一个窗口函数计算一段时间内的加油次数,从而为每一行分配一个油箱号 在外部选择中,选择您的设备和油箱加注的编号。瞧 如果将device_id=19的条件移动到最里面的suqbquery,则可以删除分区子句。速度更快,通用性更低 关于筛选子句: 仅获取给定设备的最后一个油箱 根据您的评论,定义为上次油箱从20或以下加注到100 我假设稍后的时间点对应于更高的id值。请注意,在并发写负载下,串行列可能会出现转角情况并发症 最简单的方法:颠倒顺序,从底部开始计数: 挑选* 从…起 选择*,计数*过滤器,其中按id描述为油箱的订单加油 从…起 按id DESC=100在订单上选择*,lagfuel,1,0 燃料 首先,我在加油前标记入口 然后,我通过计算这些标记来标记填充:0表示当前填充,1表示上一次填充,依此类推 最后,我在当前填充之前获得最后填充的第一个和最后一个id
将WHERE deviceid=19抛出到最里面的查询中,以仅获取单个设备的数据。我不是一个优秀的数据库专家,我会循环结果并使用计数器将其相加。当我达到100时,我读取了总数和值的数量。在纯SQL中可能可以做一些事情。。。我想。那是第一次,不是最后一次,对吗?@LaurenzAlbe:最后一次在去年圣诞节的意义上,我把我的心给了你,但就在第二天。。。。现在使用前面的明确说明。虽然在圣诞节之前。。。真的没用这太棒了,我怎么能只搜索最近的填充而不是所有填充?@Ron:定义最近的。最近就像上次一样,它从20到100,例如,因为这将每天运行,我只想要最后的填充,而不是所有的填充
SELECT min(id) AS first_id,
max(id) AS last_id,
deviceid
FROM (SELECT id, deviceid, fuel,
count(*) FILTER (WHERE refilled)
OVER (PARTITION BY deviceid ORDER BY id DESC) AS filling
FROM (SELECT id, deviceid, fuel,
fuel < lead(luel, 1, 0)
OVER (PARTITION BY deviceid ORDER BY id) AS before_fill
FROM tc_fuel
) AS refill
) AS fills
WHERE filling = 1
GROUP BY deviceid;