找到在特定流程步骤之前发生的单元的过程

时间:2014-04-07 09:53:11

标签: sql postgresql

我们正在使用php / postgresql进行公司的过程控制。 该公司正在修理单位,修复过程之后是过程控制系统。

Database structure

单位表存储有关各个单位的信息。

  • unit.id:单位的ID
  • unit.sn:单位的序列号

unit_process表存储了单位在其生命周期中经历的每个流程步骤。

  • unit_process.id:流程步骤的ID
  • unit_process.unit_id:单位的ID
  • unit_process.process_id:进程的id。

(真正的表有更多列)

一个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:

enter image description here

示例输出:

enter image description here

我希望我没有弄乱样品,我只是想出了这些例子。

3 个答案:

答案 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

DEMO

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;

new DEMO

希望它可以帮到你!

答案 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