按最大日期降序排列,然后使用 linq 方法 sintax 按日期升序排列组中的单行

Order by descending group by Max date, then order by single row in the group by date ascending using linq Method sintax

我有一个table这样的

Id      Date       GroupId   Text    Column1   Column2 ...
1    2020-02-02       1      ....     ....       ...
2    2020-02-04       1      ....     ....       ...
3    2020-02-03       1      ....     ....       ...
4    2020-02-02       2      ....     ....       ...
5    2020-02-05       2      ....     ....       ...

我需要得到这个结果:

Id      Date       GroupId   Text    Column1   Column2 ...
5    2020-02-05       2      ....     ....       ...
4    2020-02-02       2      ....     ....       ...
1    2020-02-02       1      ....     ....       ...
3    2020-02-03       1      ....     ....       ...
2    2020-02-04       1      ....     ....       ...

我解释说我需要在第 2 组的所有行之前获取,因为最大日期在第 2 组中...我需要按日期降序对组进行排序,但每个组都应按日期升序排序。

我也觉得sql很难写。谁能帮帮我吗? 谢谢

编辑: 这是我尝试做的事情:

var result = messages.Select(m => new MyViewModel()
            {
                Id = m.Id,
                Date = m.Date,
                Text = m.Text,                    
                GroupId = m.GroupId
            }).GroupBy(d => d.GroupId)
              .SelectMany(g => g)
              .OrderByDescending(x => x.GroupId)
              .ThenBy(x => x.Date);

但是不行

在SQL中,您可以使用window函数:

order by 
    max(date) over(partition by groupId),
    case when max(date) over(partition by groupId) = max(date) over() then date end desc,
    date

您想按最大日期对组进行排序。然后在每个组中,按日期降序排列。

我会为 order by 推荐这些密钥:

  1. 每组的最大日期(降序)
  2. groupId 将每个组放在一起(顺序无关紧要)
  3. 将整体最大日期放在首位的标志
  4. 所有其他行的日期(升序)

所以:

order by max(date) over (partition by groupId) desc, 
         groupId,   -- put each group together
         (case when date = max(date) over() then 1 else 2 end),
         date

我建议创建一个具有 GroupDate 属性 的中间结果。在我的示例中,我使用 C# 7.0 Tuples。如果您使用的是较旧的 C# 版本,您也可以使用匿名类型。

var result = messages
    .GroupBy(m => m.GroupId)                                // Create Tuple ...
    .Select(g => (Group: g, GroupDate: g.Max(m => m.Date))) // ... with group and group date.
    .SelectMany(a =>              // Expand the group
        a.Group.Select(m =>       // Create new tuple with group date and model.
            (a.GroupDate,
             Model: new MyViewModel() {
                 Id = m.Id,
                 Date = m.Date,
                 Text = m.Text,
                 GroupId = m.GroupId
             })))
    .OrderByDescending(x => x.GroupDate)
    .ThenBy(x => x.Model.Date)
    .Select(x => x.Model);         // Extract the view model from the tuple.

结果:

Id = 2, Date = 2020-02-02, GroupId = 2
Id = 2, Date = 2020-02-05, GroupId = 2
Id = 1, Date = 2020-02-02, GroupId = 1
Id = 1, Date = 2020-02-03, GroupId = 1
Id = 1, Date = 2020-02-04, GroupId = 1

元组示例:

var t = (X: 15, Name: "axis");
Print($"X = {t.X}, Name = {t.Name}");

元组的名称 属性 也可以像 (a.GroupDate, Model: ...) 中那样推断出来。第一个 属性 将自动称为 GroupDate。第二个明确命名为 Model.