检查指定列为空的下一个组

时间:2017-05-30 15:57:49

标签: sql sql-server group-by

我有一个批准流程,按Action(请求者,验证者和审批者)分组。逻辑是当其中一个验证者采取了行动(ActionDate有值)时,它将显示下一组的用户。这意味着,Verifier组已经验证了RequestNo R001,现在该请求应该等待审批组。我需要的是显示下一个动作(批准者)和用户。

Approval

RequestNo | UserName | Action    | Seq | ActionDate
R001      | JohnD    | Requestor | 1   | 01/01/2017
R001      | SamS     | Verifier  | 2   | NULL
R001      | TrishL   | Verifier  | 3   | 01/01/2017
R001      | GeorgeP  | Verifier  | 4   | NULL
R001      | JackF    | Approver  | 5   | NULL
R001      | RobertL  | Approver  | 6   | NULL

2 个答案:

答案 0 :(得分:1)

使用相关子查询仅返回Action等于“下一步”操作组(基于seq)的那些行,从而消除那些具有非空{{1}的组与ActionDate

not exists()

rextester演示:http://rextester.com/UPCZO55513

返回:

select ap.*
from Approval ap 
where ap.Action = (
    select top 1 ac.Action 
    from Approval ac
    where not exists (
      select 1
      from Approval i
      where i.RequestNo = ap.RequestNo
        and i.Action = ac.Action
        and i.ActionDate is not null
      )
    order by ac.seq asc
    )

答案 1 :(得分:1)

这可以通过派生表和一些窗口函数来实现,在我看来,这些函数至少比几个子查询更容易阅读和理解:

declare @Approval table(RequestNo nvarchar(10),UserName nvarchar(10),Action nvarchar(10),Seq int,ActionDate date);
insert into @Approval values ('R001','JohnD','Requestor',1,'20170101'),('R001','SamS','Verifier',2,NULL),('R001','TrishL','Verifier',3,'20170102'),('R001','GeorgeP','Verifier',4,NULL),('R001','JackF','Approver',5,NULL),('R001','RobertL','Approver',6,NULL);

with c as
(
    select RequestNo
            ,min(Seq) as MinSeq
            ,max(Seq) as MaxSeq
            ,row_number() over (partition by RequestNo order by RequestNo, min(ActionDate), min(Seq)) as rn
    from @Approval
    group by RequestNo
            ,Action
)
select a.*
from @Approval a
    join c
        on(a.RequestNo = c.RequestNo
            and a.Seq between c.MinSeq and c.MaxSeq
            and c.rn = 1
            )
order by a.RequestNo
        ,a.Seq;

输出:

+-----------+----------+----------+-----+------------+
| RequestNo | UserName |  Action  | Seq | ActionDate |
+-----------+----------+----------+-----+------------+
| R001      | JackF    | Approver |   5 | NULL       |
| R001      | RobertL  | Approver |   6 | NULL       |
+-----------+----------+----------+-----+------------+

添加其他数据以显示它在整个集合中的工作方式:

declare @Approval table(RequestNo nvarchar(10),UserName nvarchar(10),Action nvarchar(10),Seq int,ActionDate date);
insert into @Approval values
 ('R001','JohnD','Requestor',1,'20170101'),('R001','SamS','Verifier',2,NULL),('R001','TrishL','Verifier',3,'20170102'),('R001','GeorgeP','Verifier',4,NULL),('R001','JackF','Approver',5,NULL),('R001','RobertL','Approver',6,NULL)
,('R002','JohnD','Requestor',1,'20170101'),('R002','SamS','Verifier',2,NULL),('R002','TrishL','Verifier',3,null),('R002','GeorgeP','Verifier',4,NULL),('R002','JackF','Approver',5,NULL),('R002','RobertL','Approver',6,NULL);

输出:

+-----------+----------+----------+-----+------------+
| RequestNo | UserName |  Action  | Seq | ActionDate |
+-----------+----------+----------+-----+------------+
| R001      | JackF    | Approver |   5 | NULL       |
| R001      | RobertL  | Approver |   6 | NULL       |
| R002      | SamS     | Verifier |   2 | NULL       |
| R002      | TrishL   | Verifier |   3 | NULL       |
| R002      | GeorgeP  | Verifier |   4 | NULL       |
+-----------+----------+----------+-----+------------+