如何在日期范围内找到特定状态

时间:2013-10-10 22:07:53

标签: sql tsql

我正在尝试从以下表格布局中找到特定日期范围的特定legalStatus

CREATE TABLE dbo.LegalStatus (
LegalStatusID int IDENTITY,
CaseID int NOT NULL,
LegalStatusTypeID int NOT NULL,
LegalStatusDate smalldatetime NOT NULL

示例:我可能有三个状态记录。

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

我正在尝试报告在1/1/13和7/1/13之间LegalStatusTypeID = 62的所有案例。 如果有结束日期,这将很容易。 救命! 安迪

3 个答案:

答案 0 :(得分:1)

好的,如果我理解您的评论,对于给定的CaseID,您可以拥有多条记录,每条记录都有一个LegalStatusTypeID唯一的记录,每个记录都有一个日期,每个记录的适用性LegalStatusTypeID介于该记录的LegalStatusDate之间为该案例输入的下一条记录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)
        )

您需要将LegalStatusTypeID = 62的记录加入到任何给定案例的下一条记录中,然后使用下一个案例的ID来获取{{1}的适用性结束日期} = 62。

由于您在讨论日期范围内LegalStatusTypeID = 62 的案例,因此您需要开始日期在您的日期范围内,或者结束日期在您的日期范围(或两者),或您的日期范围介于案例的LegalStatusTypeID = 62个开始日期和结束日期之间。

答案 1 :(得分:0)

  SELECT *

  FROM   LegalStatus
  WHERE  LegalStatusTypeID = 62 AND
         LegalStatusDate BETWEEN '01/01/13' and '07/01/13'

答案 2 :(得分:0)

我理解你的问题是要列出所有CaseID值,其中案件的法律地位在'20130101'开始的整个期间保持在62,但不包括'20130701'。特定日期的案件的法律地位由该案件在给定日期之前或之后的最新LegalStatusTypeID值确定。

如果这就是你想要的,我想这可能会做到。

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
  )

这将选择CaseID值,其中“20130101”的状态为62,并且没有后续状态更改为“20130101”之后但“20130701”之前的值不同的值。如果这不是你想要的,也许这仍然会有所帮助。此查询假设案例的法律状态每天只能更改一次,即(CaseID,LegalStatusDate)是您的表的候选键。

我没有对它进行过多的测试,因为你提供了很少的样本数据来解释你想要的东西。

更新:原始海报在下面的评论中澄清了这个问题。以下查询应标识那些CaseID值,其中案例的法律状态在指定时间段内的任何时间点(即使只是一天)为62。它选择“20130101”状态为62的情况以及该期间内任何时候状态为62的情况。

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
  )