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

Sql 如何在日期范围内找到特定状态,sql,tsql,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 = 5

我试图从下表布局中找到特定日期范围的特定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
我正在尝试报告13年1月1日至13年7月1日期间LegalStatusTypeID=62的所有案例。 如果有一个结束日期,这将很容易。 帮助
Andy

好的,如果我理解您的评论,对于给定的案例ID,您可以有多个记录,每个记录都有该案例特有的LegalStatusTypeID,每个记录都有日期,每个LegalStatusTypeID的适用性介于该记录的LegalStatusDate和为该案例的LegalStatusDate输入的下一个记录之间:

您需要将LegalsStatusTypeId=62的记录加入任何给定案例的下一个记录,然后使用下一个案例的ID获取LegalsStatusTypeId=62的适用性结束日期


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

我理解您的问题是,在从“20130101”开始到“20130701”的整个期间内,如果案件的法律地位保持在62,则试图列出所有案件ID值。给定日期案件的法律地位由该案件在给定日期之前或当天的最新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
  )
这将选择“20130101”上的状态为62且“20130101”之后但“20130701”之前的状态不会更改为与62不同的值的CaseID值。如果这不是你想要的,也许这仍然会有帮助。此查询假设案例的法律状态每天只能更改一次,即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
  )

你的意思是:如果有一个结束日期,这将很容易?这是不是你没有告诉我们的事情让问题复杂化了?嗨,是的,只有一次约会。该日期可能被另一日期取代。在我的示例数据中,每个LegalStatusDate都有效,直到添加另一个日期为止。每次添加另一条记录时,该记录都是活动的合法状态。因此,我可以找出如何确定某个日期范围内的合法状态是否处于活动状态。在我的测试数据中,日期为12年10月1日的LegalStatus将在2013年1月1日至2013年7月1日之间激活。没有结束日期,下一个日期同时作为新记录的开始日期和上一个记录的结束日期。您好,谢谢您的回复。我需要的是一个查询,用于查找在特定日期范围内当前或已经将legalStatusTypeID=62作为当前状态的所有caseID。当前日期可能早于开始日期,并且可能存在日期介于“我的日期范围”的结束日期之间或之后的记录。例如,在我的原始示例中,数据记录2将是日期范围为1/1/13到7/1/13的当前legalstatusID,即使该记录的日期是10/1/12。这个记录是当前的legalStatusID,直到添加了日期为10/1/13的记录。我几乎已经重写了我的答案,看一看。太棒了!谢谢你的帮助。嗨,谢谢你的回复。你很接近,但不完全正确。我正在寻找一个legalstatusID,它在日期范围内的任何时候都是最新的,不一定在整个日期范围内。即使legalStatusID在日期范围内的一天内是最新的。由于未指定TSQL的版本,它可能不支持CTEs。T-SQL自SQL Server 2005起就支持CTEs。对SQLServer2000的扩展支持在今年早些时候结束了,因此在这一点上,给出对所有10年以下版本和所有仍然支持的版本都有效的答案应该是公平的。
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
  )
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
  )