简体   繁体   English

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

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

I have a table like this我有一张这样的桌子

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      ....     ....       ...

I need to obtain this result:我需要获得这个结果:

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      ....     ....       ...

I explain I need to get before all rows of the group 2 because the max date is in the group 2... I need to order the group by date descending but every single group should be ordered by date ascending.我解释说我需要在第 2 组的所有行之前获取,因为最大日期在第 2 组中......我需要按日期降序对组进行排序,但每个组都应按日期升序排序。

I find difficult to write it in sql too.我也觉得很难用 sql 编写它。 Can anyone help me please?有人可以帮我吗? Thank you谢谢

EDIT: Here what I have tried to do:编辑:这是我尝试做的:

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);

But it does not work但它不起作用

I suggest creating an intermediate result having a GroupDate property.我建议创建一个具有GroupDate属性的中间结果。 In my example I am using C# 7.0 Tuples .在我的示例中,我使用的是C# 7.0 Tuples You could use anonymous types as well, if you are using an older C# version.如果您使用的是较旧的 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.

Result:结果:

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

Example for tuple:元组示例:

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

The name of a tuple property can also be inferred like in (a.GroupDate, Model: ...) .元组属性的名称也可以像(a.GroupDate, Model: ...)那样推断。 The first property will automatically be called GroupDate .第一个属性将自动称为GroupDate The second is named explicitly Model .第二个被明确命名为Model

In SQL, you can use window functions:在 SQL 中,您可以使用窗口函数:

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

You want to order the groups by their max date.您想按最大日期对组进行排序。 Then within each group, order by the date descending.然后在每个组内,按日期降序排列。

I would recommend these keys for the order by :我会为以下order by推荐这些键:

  1. maximum date for each group (desc)每个组的最大日期(desc)
  2. groupId to keep each group together (order doesn't matter) groupId将每个组保持在一起(顺序无关紧要)
  3. flag to put the overall maximum date first将总体最大日期放在首位的标志
  4. date for all other rows (asc)所有其他行的日期(asc)

So:所以:

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

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

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