2016-10-13 15 views
3

私は行のバージョン管理を頻繁に使用する第三者DBで作業しています。通常、これは問題ではありませんが、特定のデータセットでは、フロントエンドのビジネスルールが緩やかなためです。気づくように、INNER JOINは、それぞれEmpIDの最新のEffectiveDateの行グループを取得するために使用されます。 EnrollmentStatus = 'Enrolled'という行がない限り、このロジックは常に使用されます。これが存在する場合は、この行のグループを戻す必要があります。行のグループによって私はEmpIDEffectiveDateを意味します。1つの列の値に基づいて条件付きで結果を制限する方法

以下のデータセットでは、EnrollmentStatus = 'Enrolled'というレコードが含まれているため、希望の結果は4行になります。EffectiveDate = '2015-12-15'です。 EmpIDのレコードがEnrollmentStatus = 'Enrolled'の場合、内部結合で十分です。

私はこれを行う上品な方法を見落としていると確信しています。

if object_id('tempdb..#emp') is not null drop table #emp 

create table #emp 
    (EmpID int, 
    EmpBenID int, 
    EffectiveDate datetime, 
    EligibilityDate datetime, 
    EnrollBeginDate datetime, 
    OverrideEnrollBeginDate datetime, 
    EnrollEndDate datetime, 
    OverrrideEnrollEndDate datetime, 
    EnrollStatus varchar(64)) 

insert into #emp(EmpID, EmpBenID, EffectiveDate, EligibilityDate, EnrollBeginDate,OverrideEnrollBeginDate,EnrollEndDate,OverrrideEnrollEndDate,EnrollStatus) 
values 
(1950,55403,'2015-12-15 00:00:00','1998-11-02 00:00:00',NULL,NULL,NULL,NULL,'Not Enrolled'), 
(1950,55404,'2015-12-15 00:00:00','1998-11-02 00:00:00','1998-12-01 00:00:00',NULL,NULL,NULL,'Enrolled'), 
(1950,55405,'2015-12-15 00:00:00','1998-11-02 00:00:00',NULL,NULL,NULL,NULL,'Not Enrolled'), 
(1950,55406,'2015-12-15 00:00:00','1998-11-02 00:00:00',NULL,NULL,NULL,NULL,'Not Enrolled'), 
(1950,55407,'2016-01-12 00:00:00','1998-11-02 00:00:00',NULL,NULL,NULL,NULL,'Not Enrolled'), 
(1950,55408,'2016-01-12 00:00:00','1998-11-02 00:00:00','2011-01-19 00:00:00',NULL,'2011-08-31 00:00:00',NULL,'Not Enrolled'), 
(1950,55409,'2016-01-12 00:00:00','1998-11-02 00:00:00',NULL,NULL,NULL,NULL,'Not Enrolled'), 
(1950,55410,'2016-01-12 00:00:00','1998-11-02 00:00:00',NULL,NULL,NULL,NULL,'Not Enrolled') 


select e.* 
from #emp e 
inner join 
(select EmpID, Max(EffectiveDate) dt 
from #emp 
--Attempted multiple filtering methods here while trying to avoid a sub-select 
group by EmpID) e2 on e2.EmpID = e.EmpID and e2.dt = e.EffectiveDate 
+2

申し訳ありませんが、あなたの問題の背後にある論理をまだ理解していません。あなたのサンプルは不完全であり、両方のケースでempIDが必要な結果を含む必要があります。 [** How-to-Ask **](http://stackoverflow.com/help/how-to-ask) \t \t [** START **](http ://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/)質問品質を向上させ、より良い回答を得る方法を学ぼう。 –

+0

あなたは@JuanCarlosOropezaを理解できません申し訳ありません。私はそれがあなたに役立つ場合、私は期待された結果を含めることができますが、私は期待された、または希望の結果がOPにあるべきであることに気づいた。サンプルは完成しており、私が保証できる他のEmpIDの場合にのみ複製されます。 – scsimon

+0

もう一度、私はすでにそれを理解していないと言います。問題のあなたの記述はそうでなければ完全ではありませんでした。あなたが望む結果を推測する必要はありません。 –

答えて

3

これはウィンドウ関数を使用して行いますが、それは別の問題です。私が正しく理解していれば、あなたはこのロジックをしたい:それが存在する場合は

select e.* 
from #emp e inner join 
    (select EmpID, 
      coalesce(max(case when EnrollmentStatus = 'Enrolled' then EffectiveDate end), 
         max(EffectiveDate) 
        ) dt 
     from #emp 
--Attempted multiple filtering methods here while trying to avoid a sub-select 
     group by EmpID 
    ) e2 
    on e2.EmpID = e.EmpID and e2.dt = e.EffectiveDate; 

これは、'Enrolled'の日付を取得します。それ以外の場合は、最大の日付を取得します。

+0

しかし、これは「登録済み」のレコードが1つしかありません。私は彼が望むと思う "最大の日付または**すべての**登録されたレコード" – sagi

+0

ありがとうゴードン、これは私が 'MAX(コールセッシ())を使って試していたものに近いですが、私はちょうど後方に考えていた。あなたの解決策はこれまでのところうまくいきます - そして私はそれがより大きいデータセットに期待しています。あなたの窓関数方法で精巧な心? – scsimon

+0

@scsimon。 。 。ウィンドウ関数は、最大日付と最大登録日付を別々の変数として計算し、最適なものを選択するために 'where'節を使用します。 –

1

私はこれを使用します。

select EmpID, EffectiveDate 
from #emp e1 
where EnrollStatus = 'Enrolled' 
union 
select e1.EmpID, max(e1.EffectiveDate) 
from #emp e1 
where e1.EnrollStatus <> 'Enrolled' 
and not exists (select 1 from #emp e2 where e1.EmpID = e2.EmpID and e2.EnrollStatus = 'Enrolled') 
group by e1.EmpID 

それは在籍それらのための効果的な日付、および登録されていないものの最大効果的な日付を取得します(誰がどの時点で在籍の地位を持っていない)

+0

説明できますか?あなたはあなたの組合に集まっていますが、「GROUP BY」がありません – scsimon

+0

@scsimonおっと、私の悪いこと、それを試してください – JohnHC

+0

ありがとう。これにより、データは正しい有効日に制限されますが、最後に別の結合が必要になります。私の+1。 – scsimon

関連する問題