2017-05-30 9 views
0

私はAction(リクエスタ、検証者、承認者)でグループ化された承認フローを持っています。ロジックは、検証者のいずれかがアクションを実行したとき(ActionDateの値がある)、次のグループのユーザーを表示します。つまり、VerifierグループはすでにRequestNo R001を確認しており、要求は承認者グループに保留されているはずです。私が必要とするのは、次のアクション(承認者)とユーザーを表示することです。唯一の非ヌルを有するそれらのグループを排除し、Actionが(seqに基づく)「次へ」アクション・グループに等しいそれらの行を返すように相関サブクエリを使用指定された列がヌルである次のグループを確認してください

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 
+0

はあなたのクエリは、これまでのように何を求めず、あなたはどのようなエラーを取得していますか? –

+0

入力データと予想される出力は何ですか? –

答えて

1

ActionDatenot exists()

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 
    ) 

とrextesterデモ:http://rextester.com/UPCZO55513

リターン:

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

'Request 1から承認1のWHEREステートメントの中に' AND RequestNo = 'R001'を入れましたが、結果を生成するにはSQL Serverが長すぎましたが、正しいRequestNoを表示しませんでした –

+0

@HarambeAttackHelicopter実行可能なソリューションですか?私は以下の私の答えがあなたが必要とすることをすると確信しています。 – iamdave

+0

@ HarambeAttackHelicopterあなたはそれをクエリの最も外側の部分に置くべきです。 'とap.RequestNo = 'R001'' – SqlZim

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; 

出力:追加のDATに追加

+-----------+----------+----------+-----+------------+ 
| 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  | 
+-----------+----------+----------+-----+------------+ 
関連する問題