简体   繁体   English

获取每个组的最后N个元素

[英]Get last N elements for each group

What I'm trying to do is grab the last N elements (for my example 3) for each grouping in the table. 我想做的是为表中的每个分组获取最后的N个元素(对于我的示例3)。 My table is: 我的桌子是:

create table application_sessions
(
    application_session_id int identity(1,1) primary key,
    session_type_id int not null references session_types(session_type_id),
    start_ts datetime not null,
    end_ts datetime null,
    is_successful bit not null default 0
)

In this case, I'm trying to get the last 3 entries in the table (ordered by start_ts) for each session_type_id. 在这种情况下,我试图为每个session_type_id获取表中的最后3个条目(按start_ts排序)。 To do this in SQL, I would run this: 为此,我将运行以下命令:

;with ranking as
(
    select *, row_number() over (partition by session_type_id order by start_ts desc) as rn
    from application_sessions
)
select * from ranking
where rn <= 3

I'm having some issues using NHibernate with fetching these records from the database in this way. 我在使用NHibernate以这种方式从数据库中获取这些记录时遇到了一些问题。 What would be the best way to do this given the Entity below (SessionType is an enum)? 给定下面的实体(SessionType是枚举),这样做的最佳方法是什么?

public class ApplicationSession
{
    public virtual int Id { get; set; }
    public virtual SessionType SessionType { get; set; }
    public virtual DateTime StartTimestamp { get; set; }
    public virtual DateTime? EndTimestamp { get; set; }
    public virtual bool IsSuccessful { get; set; }
}

My (failing) first attempt was this: 我(失败)的第一次尝试是:

public IList<ApplicationSession> GetLastNGroupedSessions(int count)
  {
     return _session.Query<ApplicationSession>()
                       .GroupBy(x => x.SessionType)
                       .SelectMany(y =>
                               y.OrderByDescending(z => z.StartTimestamp)
                                .Take(count))
                       .ToList();
   }

This yields the exception: Query Source could not be identified: ItemName = y, ItemType = System.Linq.IGrouping`2[RIMS.ECMS.BusinessObjects.Local.Models.SessionType,RIMS.ECMS.BusinessObjects.Local.Models.ApplicationSession], Expression = from IGrouping`2 y in {value(NHibernate.Linq.NhQueryable`1[RIMS.ECMS.BusinessObjects.Local.Models.ApplicationSession]) => GroupBy([x].SessionType, [x])} 这产生异常:无法识别查询源:ItemName = y,ItemType = System.Linq.IGrouping`2 [RIMS.ECMS.BusinessObjects.Local.Models.SessionType,RIMS.ECMS.BusinessObjects.Local.Models.ApplicationSession] ,表达式=来自{值(NHibernate.Linq.NhQueryable`1 [RIMS.ECMS.BusinessObjects.Local.Models.ApplicationSession])=> GroupBy([x] .SessionType,[x])}中IGrouping`2 y

So, it may not be the "best" solution, but it a working one. 因此,它可能不是“最佳”解决方案,但它是可行的解决方案。 One of my coworkers pointed out that NHibernate allows for you to directly execute SQL using CreateSQLQuery. 我的一位同事指出,NHibernate允许您使用CreateSQLQuery直接执行SQL。 This is the solution that I came up with that works in case anyone else runs into this type of problem. 这是我想出的解决方案,以防万一其他人遇到此类问题。

  public IList<ApplicationSession> GetLastNGroupedSessions(int count)
  {

     var sqlQuery = string.Format(@";with ranking as
     (
     select *, row_number() over (partition by session_type_id order by start_ts desc) as rn
     from application_sessions
     )
     select app.application_session_id,
        app.session_type_id,
        app.start_ts,
        app.end_ts,
        app.is_successful 
     from ranking as app
     where rn <= {0}", count);

     return _session.CreateSQLQuery(sqlQuery)
        .AddEntity("app", typeof(ApplicationSession))
        .List<ApplicationSession>();
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM