我的数据如下所示:
数据按processID排序,然后按步骤开始日期排序
步骤开始日期确定步骤的顺序。
每个步骤都经过审批人批准(下面的审批者ID是任意的)
╔═══════════╦══════════════════════════╦═══════════════╦════════════╗
║ ProcessID ║ StepName ║Step Start Date║ ApproverID ║
╠═══════════╬══════════════════════════╬═══════════════╬════════════╣
║ 1 ║ Supervisor Approval ║1/1/2013 07:24 ║ A ║
║ 1 ║ Sales Manager Approval ║1/1/2013 13:35 ║ B ║
║ 1 ║ General Manager Approval ║1/3/2013 08:00 ║ B ║
║ 1 ║ CEO Approval ║1/5/2013 14:40 ║ C ║
║ 2 ║ Supervisor Approval ║1/2/2013 07:00 ║ A ║
║ 2 ║ Sales Manager Approval ║1/2/2013 08:00 ║ B ║
║ 2 ║ General Manager Approval ║1/2/2013 09:00 ║ C ║
║ 2 ║ CEO Approval ║1/2/2013 10:00 ║ B ║
╚═══════════╩══════════════════════════╩═══════════════╩════════════╝
我需要一个TSQL查询,它会为2个或更多连续步骤中具有相同ApproverID的任何进程返回[ProcessID]。
因此,在上面的示例中,将返回ProcessID#1,因为审批者B批准了步骤2和3(连续)。不会返回ProcessID#2,因为即使审批人B批准了第2步和第4步,它们也不是连续的。
以下是使用架构设置和一些示例数据的SQL小提琴:SQL Fiddle
非常感谢任何帮助!
答案 0 :(得分:1)
这将根据您的数据集中的需要返回进程1:
with nextSteps as
(
select s.ProcessID
, disapprove = case when s.ApproverID <= n.ApproverID or n.ApproverID is null
then 0 else 1 end
from steps s
outer apply
(
select top 1 ApproverID
from steps n
where s.ProcessID = n.ProcessID
and s.StepStartDate < n.StepStartDate
order by n.StepStartDate
) n
)
select ProcessID
from nextSteps
group by ProcessID
having sum(disapprove) = 0
基本上对于每个流程步骤,我们在同一流程中进行下一步,并检查下一步是由相同或更大的审批者。
如果一行或多行失败,请不要返回ProcessID。
评论后修改:
with nextSteps as
(
select s.ProcessID
, disapprove = case when s.ApproverID = n.ApproverID then 1 else 0 end
from steps s
outer apply
(
select top 1 ApproverID
from steps n
where s.ProcessID = n.ProcessID
and s.StepStartDate < n.StepStartDate
order by n.StepStartDate
) n
)
select ProcessID
from nextSteps
group by ProcessID
having sum(disapprove) > 0
这个稍微改变的新查询适用于以下审批者模式,如SQL Fiddle:
所示进程ID 1:A,B,B,C - 应该返回连续批准者。
ProcessID 2:A,B,C,B - 没有连续批准者,不应该退回。
进程ID 3:A,B,C,D - 没有连续的批准者,不应该返回。
非常相似,检查ProcessID中每个步骤的下一行,如果至少有一个连续的批准者,则返回ProcessID。
我还检查了你添加的SQL Fiddle中的数据 - 似乎正在运行:
答案 1 :(得分:0)
这是我最终得到的结果,感谢Ian的帮助:
WITH Steps AS
(
SELECT
[CurStep].[ProcessID],
ConsecutiveApproval =
CASE
WHEN [CurStep].[ApproverID] = [NextStep].[ApproverID] THEN 1
ELSE 0
END
FROM [Processes] AS CurStep
OUTER APPLY
(
SELECT TOP 1
[NextStep].[ApproverID]
FROM
[Processes] AS NextStep
WHERE
[CurStep].[ProcessID] = [NextStep].[ProcessID]
AND [CurStep].[StepStartDate] < [NextStep].[StepStartDate]
ORDER BY [NextStep].[StepStartDate]
) AS NextStep
)
SELECT [ProcessID]
FROM [Steps]
GROUP BY [Steps].[ProcessID]
HAVING SUM([ConsecutiveApproval]) > 0