如何根据条件进行ORDER BY? SQL 服务器

How to ORDER BY based on condition? SQL Server

我下面有一个 table 例如:

ID          NAME           Company          StartDate        EndDate        Status     
--------------------------------------------------------------------------------------
50          Bob            ABC              11-15-2016       02-05-2017     Former  
50          Bob            XYZ              05-06-2014       05-06-2015     Former
50          Bob            EFG              06-10-2019       NULL           Active
50          Bob            LMN              07-05-2019       NULL           Active

我试图按降序列出他们最近的 3 个工作,因此他们的“活跃”工作将排在第一位,但如果他们有 2 个“活跃”工作,如上例,我只想拉“具有最近开始日期的“活动”工作,或者如果两个“活动”工作具有相同的开始日期,则只需随机选择其中一个,并跳过另一个活动,然后继续他们最近的前工作。 “活动”作业将始终具有 NULL EndDate 值。

所以我要查找的结果集如下所示:

ID          NAME           Company          StartDate        EndDate        Status        rn     
----------------------------------------------------------------------------------------------
50          Bob            LMN              07-05-2019       NULL           Active         1 
50          Bob            ABC              11-15-2016       02-05-2017     Former         2
50          Bob            XYZ              05-06-2014       05-06-2015     Former         3

我试过下面的代码,但它无法检查两个活动作业状态并正确地给它们一个行号。根据上述条件,我只希望其中一个 Active 作业为 rn = 1,并且 rn = 2 和 rn = 3 将是最后 2 个“前”作业:

  select *, row_number() over (partition by ID, NAME order by CASE WHEN Status = 'Active' AND 
  EndDate is NULL THEN Status END desc, EndDate desc
  ) rn
  from employment

您可以使用 CTE 获取最新的 Active 作业和 Former 作业的 rn,然后 UNION 两者:

;with cte1 as
(
select Id, Name, C.Company, C.StartDate, C.EndDate, C.Status, rn = 1
From employment E
Outer Apply
(
    Select top 1    E2.Company,
                    E2.StartDate,
                    E2.EndDate,
                    E2.Status
    From employment E2
    where E.Id = E2.Id and E.Name = E2.Name
    and E2.Status = 'Active'
    order by E2.StartDate desc
) C
group by E.Id, E.Name, C.Company, C.StartDate, C.EndDate, C.Status
),
cte2 as
(
  select *, 1 + row_number() over (partition by ID, NAME order by StartDate desc
  ) rn
  from employment
  where Status = 'Former'
)   
    select * from cte1
   union
    select * from cte2
    where rn <= 3
   order by Id asc, Name asc, StartDate desc

输出:

您可以使用 window 函数来做到这一点。假设“活跃”和“前任”是仅有的两个可能的状态值,您可以这样做:

select *
from (
    select t.*, 
        row_number() over (partition by id, status order by startDate desc) rn
    from mytable t
) t
where 
    (status = 'Active' and rn = 1)
    or (status <> 'Active' and rn <= 2)

如果可能还有其他状态,那么您可以将window函数更改为:

row_number() over (
    partition by id, case when status = 'Active' then 1 else 0 end 
    order by startDate desc
) rn

最后,如果您想使用 startDate 订购“有效”记录并 endDate 订购其他记录:

row_number() over (
    partition by id, case when status = 'Active' then 1 else 0 end 
    order by case when status = 'Active' then startDate else endDate end desc
) rn