Sql server SQL Server-选择具有条件的最新记录
我有一张这样的桌子 表:Sql server SQL Server-选择具有条件的最新记录,sql-server,select,group-by,Sql Server,Select,Group By,我有一张这样的桌子 表: ID EnrollDate ExitDate 1 4/1/16 8/30/16 2 1/1/16 null 2 1/1/16 7/3/16 3 2/1/16 8/1/16 3 2/1/16 9/1/16 4 1/1/16 12/12/16 4 1/1/16 12/12/16 4 1/1/16 12/12/16 4 1/1/16 null 5
ID EnrollDate ExitDate
1 4/1/16 8/30/16
2 1/1/16 null
2 1/1/16 7/3/16
3 2/1/16 8/1/16
3 2/1/16 9/1/16
4 1/1/16 12/12/16
4 1/1/16 12/12/16
4 1/1/16 12/12/16
4 1/1/16 null
5 5/1/16 11/12/16
5 5/1/16 11/12/16
5 5/1/16 11/12/16
需要选择具有这些条件的最新记录
ID EnrollDate ExitDate
1 4/1/16 8/30/16
2 1/1/16 null
3 2/1/16 9/1/16
4 1/1/16 null
我用groupby编写了查询。我不知道如何选择条件2和3
select t1.* from table t1
INNER JOIN(SELECT Id,MAX(EnrollDate) maxentrydate
FROM table
GROUP BY Id)t2 ON EnrollDate = t2.maxentrydate and t1.Id=t2.Id
请告诉我最好的方法是什么。使用rank()
窗口函数,我认为这是可能的
这是未经测试的,但它应该可以工作:
select t.ID, t.EnrollDate, t.ExitDate
from (select t.*,
rank() over(
partition by ID
order by EnrollDate desc,
case when ExitDate is null then 1 else 2 end,
ExitDate desc) as rnk
from tbl t) t
where t.rnk = 1
group by t.ID, t.EnrollDate, t.ExitDate
having count(*) = 1
基本思想是rank()
窗口函数将对值为1
的最“最近”行进行排序,我们在外部查询的where
子句中对其进行筛选
如果多行具有相同的“最新”数据,则它们都将共享相同的
1
,但会被having count(*)=1
子句过滤掉。使用行号
和大小写
表达式来获得所需的结果:
WITH Cte AS(
SELECT t.*,
ROW_NUMBER() OVER(
PARTITION BY t.ID
ORDER BY
t.EnrollDate DESC,
CASE WHEN t.ExitDate IS NULL THEN 0 ELSE 1 END,
t.ExitDate DESC
) AS rn
FROM Tbl t
INNER JOIN (
SELECT
ID,
COUNT(DISTINCT CHECKSUM(EnrollDate, ExitDate)) AS DistinctCnt, -- Count distinct combination of EnrollDate and ExitDate per ID
COUNT(*) AS RowCnt -- Count number of rows per ID
FROM Tbl
GROUP BY ID
) a
ON t.ID = a.ID
WHERE
(a.DistinctCnt = 1 AND a.RowCnt = 1)
OR a.DistinctCnt > 1
)
SELECT
ID, EnrollDate, ExitDate
FROM Cte c
WHERE Rn = 1
中的行编号
子句负责处理条件2和3ORDER BY
和internaljoin
子句负责1和4WHERE
with B as (
select id, enrolldate ,
exitdate,
row_number() over (partition by id order by enrolldate desc, case when exitdate is null then 0 else 1 end, exitdate desc) rn
from ab )
select b1.id, b1.enrolldate, b1.exitdate from b b1
left join b b2
on b1.rn = b2.rn -1 and
b1.id = b2.id and
b1.exitdate = b2.exitdate and
b1.enrolldate = b2.enrolldate
where b1.rn = 1 and
b2.id is nULL