选择后面没有特定行的行

时间:2013-11-20 09:27:21

标签: sql sql-server-2008

我有候选人名单的表格,并与候选人状态的历史相关联:

CandidateId  FirstName  LastName  
--------------------------------
1            User       One
2            User       Two

CandidateStatusId   CandidateId  Status         Timestamp
--------------------------------------------------------
1                   1            Assigned         ...
2                   1            Interviewed      ...
3                   1            Offer Accepted   ...

1                   2            Assigned         ...
2                   2            Interviewed      ...
3                   2            Offer Accepted   ...
4                   2            Hired            ...
5                   2            Bench            ...
6                   2            Hired            ...

1                   3            Assigned         ...
2                   3            Interviewed      ...
3                   3            Offer Accepted   ...
4                   3            Hired            ...
5                   3            Bench            ...

我希望具有最后状态的精选候选人是“已接受录取”,之前从未被“雇用”。在我的例子中,只有第一个用户应该被选中,因为第二个用户已被雇用,第三个用户之前被雇用(实际上是在工作台上)。

UPD:我准备了SQL语句,它应该过滤用户但不确定它的速度,用户数量可能会很大:

SELECT * FROM dbo.CandidatePositionStatus
WHERE CandidateId=34841
AND 'Hired' NOT IN (SELECT Status FROM dbo.CandidatePositionStatus WHERE CandidateId=34841)

但我不知道如何将其嵌入另一个选择提供CandidateId

UPD2:我准备了另一个查询,但它只是检查候选人是否具有OA状态并且没有“HR”状态,但查询速度仍然是打开的问题。

SELECT DISTINCT CandidateId
FROM dbo.CandidatePositionStatus
WHERE
    CandidateId IN (
        SELECT CandidateId FROM dbo.CandidatePositionStatus WHERE PositionStatusForCandidateCode='Offer Accepted' AND FirstWorkingDay IS NOT NULL
    )
    AND CandidateId NOT IN (
        SELECT CandidateId FROM dbo.CandidatePositionStatus WHERE PositionStatusForCandidateCode='Gired'
    )

2 个答案:

答案 0 :(得分:0)

根据您的要求,我写了这个。

未经测试。

select CandidateId
from dbo.CandidatePositionStatus
group by CandidateId
having sum(case when PositionStatusForCandidateCode = 'Offer Accepted' then 1 else 0 end) = 1
and    sum(case when PositionStatusForCandidateCode = 'Hired' then 1 else 0 end) = 0;

答案 1 :(得分:0)

请检查以下查询是否足够。我省略了Hire的情况,因为基本检查是针对最后一个值Offer Accepted

select 
    CandidateId
From(
    select 
        *, 
        MAX(CandidateStatusId) over(partition by CandidateId) MaxVal
    From  
        CandidatePositionStatus
)x
where MaxVal=CandidateStatusId and [Status]='Offer Accepted'