Reputation: 31
I am trying to find a specific legalStatus
for a specific date range from the following table layout.
CREATE TABLE dbo.LegalStatus (
LegalStatusID int IDENTITY,
CaseID int NOT NULL,
LegalStatusTypeID int NOT NULL,
LegalStatusDate smalldatetime NOT NULL
Example: I may have three status records.
LegalStatusID = 1,
CaseID =17,
LegalStatusTypeID = 52,
LegalStatusDate = 4/1/12
LegalStatusID = 2,
CaseID =17,
LegalStatusTypeID = 62,
LegalStatusDate = 10/1/12
LegalStatusID = 3,
CaseID =17,
LegalStatusTypeID = 72,
LegalStatusDate = 10/1/13
I am trying to report on all cases that have LegalStatusTypeID
= 62 between 1/1/13 and 7/1/13.
This would be easy if there was an end date.
Help!
Andy
Upvotes: 0
Views: 234
Reputation: 7184
I'm understanding your question as seeking to list all CaseID values where the legal status for the case remains at 62 for the entire period that starts on '20130101' and goes up to but not including '20130701'. The legal status of a case on a given date is determined by the most recent LegalStatusTypeID value for that case before or on the given date.
If that's what you want, I think this might do it.
declare @fromD smalldatetime = '20130101';
declare @uptoD smalldatetime = '20130701';
with Cases as (
select distinct CaseID
from LegalStatus
)
select CaseID
from Cases
where (
select top (1) LegalStatusTypeID
from LegalStatus as L
where L.CaseID = Cases.CaseID
and LegalStatusDate <= @fromD
order by LegalStatusDate desc
) = 62 and not exists (
select *
from LegalStatus as L
where L.CaseID = Cases.CaseID
and LegalStatusDate > @fromD
and LegalStatusDate <= @uptoD
and LegalStatusTypeID <> 62
)
This selects CaseID values for which the status on '20130101' is 62 and for which there is no subsequent status change to a value different from 62 after '20130101' but before '20130701'. If that's not what you want, perhaps this will still help. This query assumes that the legal status of a case can only change once per day, i.e., that (CaseID,LegalStatusDate) is a candidate key for your table.
I didn't test it very much, since you provided so little sample data to explain what you wanted.
Update: The original poster has clarified the question in a comment below. The following query should identify those CaseID values where the legal status for the case was 62 at any point (even just for one day) during the specified period. It selects those cases where the status was 62 on '20130101' together with those cases where the status became 62 at any point within the period.
with Cases as (
select distinct CaseID
from LegalStatus
)
select CaseID
from Cases
where (
select top (1) LegalStatusTypeID
from LegalStatus as L
where L.CaseID = Cases.CaseID
and LegalStatusDate <= @fromD
order by LegalStatusDate desc
) = 62 or exists (
select *
from LegalStatus as L
where L.CaseID = Cases.CaseID
and LegalStatusDate > @fromD
and LegalStatusDate < @uptoD
and LegalStatusTypeID = 62
)
Upvotes: 0
Reputation: 4001
OK, if I understand your comment, for a given CaseID
, you can have multiple records, each with with a LegalStatusTypeID
unique to that case, each with a date, and the applicability for each LegalStatusTypeID
is between that record's LegalStatusDate
and the next record entered for that case's LegalStatusDate
:
SELECT qrySub.CaseID, qrySub.LegalStatusDate, LegalStatus.LegalStatusDate AS
NextLegalStatusDate
FROM (
SELECT LegalStatus_2.LegalStatusID, LegalStatus_2.CaseID, LegalStatus_2.
LegalStatusTypeID, LegalStatus_2.LegalStatusDate, MIN(qryNext.
LegalStatusID) AS NextLegalStatusID
FROM LegalStatus AS LegalStatus_2
LEFT JOIN (
SELECT LegalStatusID, CaseID, LegalStatusTypeID, LegalStatusDate
FROM LegalStatus AS LegalStatus_1
) AS qryNext
ON LegalStatus_2.CaseID = qryNext.CaseID AND LegalStatus_2.LegalStatusID
< qryNext.LegalStatusID
GROUP BY LegalStatus_2.LegalStatusID, LegalStatus_2.CaseID, LegalStatus_2.
LegalStatusTypeID, LegalStatus_2.LegalStatusDate
HAVING (LegalStatus_2.LegalStatusTypeID = 62)
) AS qrySub
LEFT JOIN LegalStatus
ON qrySub.NextLegalStatusID = LegalStatus.LegalStatusID
WHERE (
qrySub.LegalStatusDate BETWEEN CONVERT(DATETIME, '2013-01-01 00:00:00'
, 102) AND CONVERT(DATETIME, '2013-07-01 00:00:00', 102)
) OR (
LegalStatus.LegalStatusDate BETWEEN CONVERT(DATETIME,
'2013-01-01 00:00:00', 102) AND CONVERT(DATETIME,
'2013-01-07 00:00:00', 102)
) OR (qrySub.LegalStatusDate < CONVERT(DATETIME, '2013-01-01 00:00:00', 102)
) AND (
LegalStatus.LegalStatusDate > CONVERT(DATETIME, '2013-01-07 00:00:00',
102)
)
You need to join the records for LegalStatusTypeID
= 62 to the next record for any given case, then use the ID of that next case to get the date which is the end of applicability of the LegalStatusTypeID
= 62.
Since you are talking about cases which had a LegalStatusTypeID
= 62 during your date range, you need cases where the start date is in your date range, or the end date is in your date range (or both), or your date range is between the case's LegalStatusTypeID
= 62 start and end dates.
Upvotes: 1
Reputation: 1130
SELECT *
FROM LegalStatus
WHERE LegalStatusTypeID = 62 AND
LegalStatusDate BETWEEN '01/01/13' and '07/01/13'
Upvotes: 0