具有多个基于时间的条件的SQL查询

时间:2014-11-12 01:34:29

标签: sql ms-access

我有一个管理血铅水平的数据库,我们有各种报告/排除要求 要从我所在区域强制删除某人,他们需要进行34岁以上的测试,在他们被允许返回之前,他们需要连续3次测试才能在27岁以下。我一直在使用下面的查询来查找应该被删除的人看看他们的任何超过34的最后3次测试,这可以说一个人必须根据他们的最后3次测试被排除在外,但不能生成一份当前应被排除的完整人员列表

SELECT x1.[Employee ID]
FROM [Lead Results] AS x1 INNER JOIN Employees ON x1.[Employee ID] = Employees.[Employee ID]
WHERE (((x1.[Test Result])>34) AND (((select count(*)
        from [Lead Results] x2
        where x2.[Employee ID] = x1.[Employee ID]
        and x2.[Date of Test] >= x1.[Date of Test]
    ))<=3))
GROUP BY x1.[Employee ID]
HAVING ((Count(x1.[Date of Test]))>=1);

我还查询了一些人,他们在27岁以下进行了最后3次测试。这样可以说有人现在可以退回了,

SELECT x1.[Employee ID]
FROM [Lead Results] AS x1 INNER JOIN Employees ON x1.[Employee ID] = Employees.[Employee ID]
WHERE (((x1.[Test Result])<27) AND (((select count(*)
        from [Lead Results] x2
        where x2.[Employee ID] = x1.[Employee ID]
    and x2.[Date of Test] >= x1.[Date of Test]
    ))<=3))
GROUP BY x1.[Employee ID], Employees.[Current Employee]
HAVING ((Count(x1.[Date of Test]))>=3);

显然这两个查询有效但仅适用于最后3次测试。

我如何为那些已经测试超过34岁的人获得所有员工ID,但是由于他们的高成绩,他们还没有在27岁以下进行过3次连续测试。

1 个答案:

答案 0 :(得分:1)

从您最近测试34的日期开始:

select [Employee ID], max([Date of Test]) as max34
from [Lead Results]
where [Test Result] > 34
group by [Employee ID];

接下来,计算最近的日期,其中有三项测试都在27以下。这有点难,但可以做到。

以下实际上找到了上一个,下一个和当前都小于27的测试。然后聚合这些以获得最新值。

select [Employee ID], max([Date of Test]) as MiddleTest27
from [Lead Results] as lr
where [Test Result] < 27 and
      (select top 1 [Test Result]
       from [Lead Results] as lr2
       where lr2.[Employee ID] = lr.[Employee ID] and lr2.[Date of Test] < lr.[Date of Test]
       order by [Date of Test] desc, id desc
      ) < 27 and
      (select top 1 [Test Result]
       from [Lead Results] as lr2
       where lr2.[Employee ID] = lr.[Employee ID] and lr2.[Date of Test] > lr.[Date of Test]
       order by [Date of Test] asc, id asc
      ) < 27
group by [Employee ID]

接下来,我们可以将这些组合起来得到你想要的东西:最近一次测试是在第一个查询而不是第二个查询的员工:

select e34.*
from (select [Employee ID], max([Date of Test]) as max34
      from [Lead Results]
      where [Test Result] > 34
      group by [Employee ID]
     ) as e34 left join
     (select [Employee ID], max([Date of Test]) as MiddleTest27
      from [Lead Results] as lr
      where [Test Result] < 27 and
            (select top 1 [Test Result]
             from [Lead Results] as lr2
             where lr2.[Employee ID] = lr.[Employee ID] and lr2.[Date of Test] < lr.[Date of Test]
             order by [Date of Test] desc, id desc
            ) < 27 and
            (select top 1 [Test Result]
             from [Lead Results] as lr2
             where lr2.[Employee ID] = lr.[Employee ID] and lr2.[Date of Test] > lr.[Date of Test]
             order by [Date of Test] asc, id asc
            ) < 27
      group by [Employee ID]
     ) as e27
     on e34.[Employee ID] = e27.[Employee ID]
where e27.[Employee ID] is NULL or e27.MiddleTest27 < e34.max34

也就是说,没有最近的“27”序列或最后一个序列在“34”序列之前。