【问题标题】:Order by descending group by Max date, then order by single row in the group by date ascending using linq Method sintax按最大日期按组降序排序,然后使用 linq Method sintax 按日期升序按组中的单行排序
【发布时间】:2020-05-20 10:09:33
【问题描述】:

我有一张这样的桌子

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 server 2012
  • 您可以使用 Linq 并将其分成两部分 - 获取最大日期和排序

标签: c# sql sql-server linq entity-framework-6


【解决方案1】:

在 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

【讨论】:

  • 问题是他们希望最大日期的组按日期降序排列,所有其他组按日期升序排列。
  • @GMB 它不起作用......而且这些组按日期升序排序
【解决方案2】:

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

我会为order by 推荐这些键:

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

所以:

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

【讨论】:

  • @Ciccio 。 . . “不起作用”根本没有帮助。它会产生错误吗?不做你想做的事?指定的逻辑是对您的问题的误解吗?
  • 我在帖子中粘贴了您查询结果的图片
  • @Ciccio 。 . .这看起来不像这个答案的结果。第一个 order by 键上有 desc 吗?
【解决方案3】:

我建议创建一个具有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,日期 = 2020-02-02,GroupId = 2
Id = 2,日期 = 2020-02-05,GroupId = 2
ID = 1,日期 = 2020-02-02,GroupId = 1
Id = 1,日期 = 2020-02-03,GroupId = 1
Id = 1,日期 = 2020-02-04,GroupId = 1

元组示例:

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

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

【讨论】:

  • 哇,是的..这是我需要的!!!我刚刚使用了匿名类型而不是元组......太好了......谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 2018-04-15
  • 2020-02-08
  • 1970-01-01
相关资源
最近更新 更多