Podczas gdy sprawdziłem inne posty dotyczące nakładających się zakresów dat, których nie znalazłem na ten problem.

Mam dwie tabele, jednego dla historii atrybutów użytkownika

MEMBERCODE |   START_DATE   |   END_DATE    | ATTRIBUTE

423223     |   10/01/2020   |  12/31/9999   | Dual
423223     |   11/01/2020   |  11/30/2020   | Cost Share

Następnie istnieje kolejna tabela dla każdego członkostwa lub historii "rejestracji".

MEMBERCODE |   EFFECTIVE_DATE |  TERM_DATE  |  PLAN_PRODUCT

423223     |   11/01/2020     |  12/31/9999 |  Foo
423223     |   09/01/2020     |  09/30/2020 |  Bar

Członkowie większość obecnej rozpiętości atrybutu powinna zawsze mieścić się w najnowszym rozpiętości rejestracji członka, ale może być więcej niż jeden atrybut na rozpiętość rejestracji.

Problem polega na tym, że chcę znaleźć wszystkie rozpiętość atrybutów z historii członka, która nie leżą w pełni w jakikolwiek rozpiętość rejestracji z ich historii.
Na przykład dla tej atrybutu rozpiętości:
10/1/2020 12/31/9999 ** Nie ma okresu nr 10/1 w ramach żadnych rozpowszechnienia dla tego członka. Wchodzi w okresie szczeliny.

SELECT a.MEMBER_NBR, a.START_DATE, A.END_DATE,B.EFFECTIVE_DATE ,B.TERM_DATE,
A.ATTRIBUTE,B.PLAN_PRODUCT
FROM Attribute_Spans A
JOIN Enrollment_Spans B ON A.MemberCode = B.MemberCode
WHERE ((A.Start_Date NOT BETWEEN B.Effective_Date and B.End_Date) AND (A.End_date NOT BETWEEN 
B.Effective_Date and B.End_Date))
AND A.MemberCode = B.MemberCode

To nie działa, ponieważ znajduje się zakres zakresów daty atrybutów, które nie mieszczą się w zasięgu zakresu rejestracji, ale zakres atrybutu spada w innym zakresie zakresów rejestracji dla tego konkretnego członka

Co dostaję

MEMBER_CODE | START_DATE | END_DATE   | EFFECTIVE_DATE | TERM_DATE  | ATTRIBUTE | PLAN_PRODUCT
423223      | 10/01/2020 | 12/31/2020 | 09/01/2020     | 09/30/2020 | Dual      | Bar
423223      | 10/01/2020 | 12/31/2020 | 11/01/2020     | 12/31/2020 | Dual      | Foo
423223      | 11/01/2020 | 11/30/2020 | 09/01/2020     | 09/30/2020 | Cost Share| Bar

Czego oczekuję

MEMBER_CODE | START_DATE | END_DATE   | EFFECTIVE_DATE | TERM_DATE  | ATTRIBUTE | PLAN_PRODUCT
423223      | 10/01/2020 | 12/31/2020 | 09/01/2020     | 09/30/2020 | Dual      | Bar
423223      | 10/01/2020 | 12/31/2020 | 11/01/2020     | 12/31/2020 | Dual      | Foo

Jakiś kod rozrusznika do tworzenia tabel

CREATE TABLE Attribute_Spans (
MemberCode int,
StartDate date,
EndDate date,
Attribute char(50)
)
INSERT INTO Attribute_Spans (MemberCode,StartDate,EndDate,Attribute)
VALUES (423223,'10/01/2020','12/31/9999','Dual'),
        (423223,'11/01/2020','11/30/2020','Cost Share')

CREATE TABLE Enrollment_Spans (
    MemberCode int,
    Effective_Date date,
    End_Date date,
    PlanProduct char(50)
    )
INSERT INTO Enrollment_Spans (MemberCode,Effective_Date,End_Date,Plan_Product)
VALUES (423223,'09/01/2020','09/30/2020','Foo'),
        (423223,'11/01/2020','12/30/2020','Bar')
sql
1
Ben Smith 21 listopad 2020, 00:09

1 odpowiedź

Najlepsza odpowiedź

Użyj not exists:

select a.*
from attribute_spans a
where not exists (select 1
                  from Enrollment_Spans es
                  where es.membercode = a.membercode and
                        a.end_date > es.effective_date and
                        a.start_date < es.end_date 
                 );

Dwa okresy nakładają się, jeśli jeden zaczyna się przed drugim końcem. I jeden kończy się po drugim start.

Nie uważa to za zakończenie / wykorzystywanie tego samego dnia jako nakładanie się. Jeśli chcesz, aby liczyć, zmień > i < do >= i <=.

1
Gordon Linoff 20 listopad 2020, 21:15