根据条件按结果获取组中的第一条记录

get first record in group by result base on condition

这是我的数据库结构 首先创建数据库testGroup; 去

use testGroupfirst;
go

create table testTbl (

id int primary key identity,name nvarchar(50) ,year int ,degree int , place  nvarchar(50)

)

insert into testTbl values ('jack',2015,50,'giza')
insert into testTbl values ('jack',2016,500,'cai')
insert into testTbl values ('jack',2017,660,'alex')
insert into testTbl values ('jack',2018,666,'giza')
insert into testTbl values ('jack',2011,50,'alex')
insert into testTbl values ('rami',2015,5054,'giza')
insert into testTbl values ('rami',2016,1500,'cai')
insert into testTbl values ('rami',2017,66220,'giza')
insert into testTbl values ('rami',2018,6656,'alex')
insert into testTbl values ('rami',2011,540,'cai')
insert into testTbl values ('jack',2010,50,'cai')
select * from testTbl

这是目前的结果

我通过

创建了简单的组

select testTbl 中的姓名、年份、学位、地点按姓名、年份、学位、地点分组

如图2所示-我想获取第一个用户的数据和他们第一年的详细描述 - cursor 可以做到这一点,但我不想使用它,而且我认为有很多方法可以更好地处理这种情况,比如 cross apply 或 cte 。 我在这里找到了一个相关的问题 Get top 1 row of each group 但这在我的情况下不起作用或者我无法应用它所以我在这里提出了这个新问题。

所以我需要从每个组(用户)中获取第一行(前 1 行)并且想要获取第一条记录并且必须包含用户在其中工作的第一年(按 desc 排序)

使用ROW_NUMBER:

SELECT name, year, degree, place
FROM
(
    SELECT name, year, degree, place,
        ROW_NUMBER() OVER (PARTITION BY name ORDER BY year) rn
    FROM testTbl
) t
WHERE rn = 1;

如果您想考虑 return 连接的可能性,例如,一个给定的名称有两个或多个具有相同最低年份的记录,则有很多选项。一种方法是向行号调用中使用的 ORDER BY 子句添加其他条件,以打破平局。另一种选择是使用排名函数而不是行号,并且 return 所有联系。

可能的解决方案之一是:

select name, year, degree, place
from
(select 
    name, 
    year,
    degree,
    place,
    row_number() over (partition by name order by year) rn
from testTbl 
--group by name ,YEAR ,degree,place -- not really needed
) r
where rn = 1;

更新:另一种解决方案(因为我和 Tim 发布的相同)是使用 CROSS APPLY:

select t.* 
from testTbl t
    cross apply (select top 1 id from testTbl where name = t.name order by year) r
where t.id = r.id