【问题标题】:get first record in group by result base on condition根据条件按结果获取组中的第一条记录
【发布时间】:2018-04-27 12:20:22
【问题描述】:

这是我的数据库结构 创建数据库testGroupfirst; 去

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

这是迄今为止的结果

我创建了一个简单的组

按名称、年份、学位、地点从 testTbl 组中选择姓名、年份、学位、地点

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

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

【问题讨论】:

    标签: sql-server group-by sql-order-by filtering common-table-expression


    【解决方案1】:

    使用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;
    

    如果您想考虑返回平局的可能性,例如,一个给定的名字有两个或多个相同最低年份的记录,有很多选项。一种是在调用行号时使用的ORDER BY 子句中添加其他条件,以打破平局。另一种选择是使用排名函数而不是行号,并返回所有平局。

    【讨论】:

      【解决方案2】:

      可能的解决方案之一是:

      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
      

      【讨论】:

      • 您的第一个查询在我看来是错误的。为什么在这里使用GROUP BY 和行号?
      • @TimBiegeleisen 我复制了 OP 的查询并在其上构建。但你是绝对正确的,你不需要GROUP BY。而且我很确定优化器甚至会忽略它。
      猜你喜欢
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 2022-12-09
      • 2022-12-11
      • 2022-10-14
      • 2017-05-08
      • 2019-12-28
      • 1970-01-01
      相关资源
      最近更新 更多