我们正在使用php / postgresql进行公司的过程控制。 该公司正在修理单位,修复过程之后是过程控制系统。
单位表存储有关各个单位的信息。
unit_process表存储了单位在其生命周期中经历的每个流程步骤。
(真正的表有更多列)
一个sql,按时间顺序查找单位的流程步骤:
SELECT process_id
FROM unit
INNER JOIN unit_process on unit.id=unit_process.unit_id
ORDER BY unit_process.id
我想创建一个查询,查找在具有特定process_id的流程步骤之前发生的所有流程步骤
所以我有一个process_id,我需要找到在具有该process_id的进程之前发生的所有unit_process行
目前我正在使用我能想象的最糟糕的方法。
例如,假设我需要在process_id = 17
的流程之前发生的所有先前流程步骤首先,我列出了具有process_id = 17
进程的单位SELECT unit.id
FROM unit
INNER JOIN unit_process on unit.id=unit_process.unit_id
WHERE process_id=17
然后我将它们存储在php数组中。
其次,我使用一个php foreach,它包含了我从上一个查询得到的每个单位ID的以下查询。
SELECT id,process_id
FROM unit_process
WHERE unit_id=$unit_id
ORDER BY id
在此之后,我可以很容易地找到使用php在process_id = 17进程步骤之前的进程,因为我只需要找到仍然低于(process_id = 17)的最大id值。
在foreach中可以使用多达数千个查询,我想改变它,但我没有足够的SQL知识来自己完成。
是否可以在单个查询中执行此操作?
示例输入 需要绿色,黄色是process_id = 17个单位。请注意,还需要process_id = 17:
示例输出:
我希望我没有弄乱样品,我只是想出了这些例子。
答案 0 :(得分:2)
我认为您正在寻找领先/滞后窗口功能。请在此处查看专家解释:How to compare the current row with next and previous row in PostgreSQL?
答案 1 :(得分:1)
我不熟悉postgresql,所以我的答案是使用SQL Server语法,
Declare @fkProcessID int = 17
select ab.unit_id,ab.id from unit_process as a
outer apply
(
select top 1 * from unit_process as b
where a.id > b.id
order by b.id desc
)as ab
where a.process_id = @fkProcessID
order by ab.unit_id
postgreSQL,错过了变量声明,但其他一切都正常。
select ab.unit_id,ab.id from unit_process as a
cross join LATERAL
(
select * from unit_process as b
where a.id > b.id
order by b.id desc
LIMIT 1
)as ab
where a.process_id = 17
order by ab.unit_id;
希望它可以帮到你!
答案 2 :(得分:0)
尝试类似:
select p2.unit_id, p2.id
from unit_process p1
join unit_process p2 on p1.unit_id = p2.unit_id and p1.id > p2.id
where p1.process_id=17
order by p2.unit_id, p2.id