Mysql 如何使用SQL查询在此表中找到正确的前一状态行?
设想一个用于数据输入的工作流。一些表格被输入到系统中,经过审核,并有望获得批准。但是,经理可能会拒绝它们,并且必须重新输入 因此,理想的工作流程如下所示:Mysql 如何使用SQL查询在此表中找到正确的前一状态行?,mysql,sql,Mysql,Sql,设想一个用于数据输入的工作流。一些表格被输入到系统中,经过审核,并有望获得批准。但是,经理可能会拒绝它们,并且必须重新输入 因此,理想的工作流程如下所示: form_id status updated_by updated_at 1 received Bob (timestamp) 1 entered Bob (timestamp) 1 approved Susan (timestamp) 2
form_id status updated_by updated_at
1 received Bob (timestamp)
1 entered Bob (timestamp)
1 approved Susan (timestamp)
2 received Bob (timestamp)
2 entered Bob (timestamp)
2 rejected Susan (timestamp)
2 entered Carla (timestamp)
2 rejected Susan (timestamp)
2 entered Sam (timestamp)
2 approved Susan (timestamp)
接收>输入>批准
但这可能发生:
接收>输入>拒绝>输入>拒绝>批准
在每个阶段,我们都会记录谁将表单更新到当前状态-谁输入、谁拒绝或谁批准了表单。因此表单状态表如下所示:
form_id status updated_by updated_at
1 received Bob (timestamp)
1 entered Bob (timestamp)
1 approved Susan (timestamp)
2 received Bob (timestamp)
2 entered Bob (timestamp)
2 rejected Susan (timestamp)
2 entered Carla (timestamp)
2 rejected Susan (timestamp)
2 entered Sam (timestamp)
2 approved Susan (timestamp)
我想做的是:写一份拒绝报告。我希望每一次被拒绝都有一行,加入到这一行中,我想看看谁做了被拒绝的工作
作为一个人,我可以看到,对于状态为“拒绝”的给定状态行,将告诉我谁做了错误工作的行将是
共享相同的表单\u id和
具有最接近拒绝的先前时间戳。
但我很难告诉你
有人知道如何构造此查询吗?您希望获得被拒绝的时间戳,然后根据时间戳找出出现在它前面的条目。我假设时间戳实际上包含一个日期/时间,而不是一个完全不同的SQLServer时间戳字段
declare @rejectedTimestamp timestamp
select @rejectedTimestamp = timestamp
from table
where status = 'rejected'
select top 1 *
from table
where timestamp < @rejectedtimestamp
order by timestamp desc
一个次级选择最终为我工作
SELECT
`s1`.`form_id`,
(
SELECT
`s2`.`updated_by`
FROM
statuses s2
WHERE
`s2`.`form_id` = `s1`.`form_id`
AND
`s2`.`updated_at` < `s1`.`updated_at`
ORDER BY
`s2`.`updated_at` DESC
LIMIT 1
) AS 'made_rejected_change'
FROM
statuses s1
WHERE
`s1`.`status` = 'rejected'
另一种解决方案,这次使用subselect而不是相关子查询:
SELECT
w1.*,
w2.entered_by
FROM (
SELECT
wr.form_id,
wr.updated_at AS rejected_at,
wr.updated_by AS rejected_by,
MAX(we.updated_at) AS entered at
FROM workflow wr
INNER JOIN workflow we ON we.status = 'entered'
AND wr.form_id = we.form_id
AND wr.updated_at > we.updated_at
WHERE wr.status = 'rejected'
GROUP BY
wr.form_id,
wr.updated_at,
wr.updated_by
) w1
INNER JOIN workflow w2 ON w1.form_id = w2.form_id
AND w1.entered_at = w2.updated_at
subselect列出了所有拒绝者和前面输入的时间戳。然后再次连接该表,以提取与输入的时间戳对应的名称。标准SQL时间戳同时包含日期和时间。Microsoft SQL Server Transact-SQL时间戳与标准SQL时间戳不同。这就是我试图在上面创建的区别。由于OP发布问题的方式表明时间戳包含一些有意义的数据,因此我以同样的方式回答了问题,您应该将术语SQL timestamp更改为SQL Server timestamp以明确这一点。标准SQL时间戳由日期和时间组成。但这与问题无关,因为它涉及MySQL。