按最大日期降序排列,然后使用 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
推荐这些密钥:
- 每组的最大日期(降序)
groupId
将每个组放在一起(顺序无关紧要)
- 将整体最大日期放在首位的标志
- 所有其他行的日期(升序)
所以:
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
.
我有一个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
推荐这些密钥:
- 每组的最大日期(降序)
groupId
将每个组放在一起(顺序无关紧要)- 将整体最大日期放在首位的标志
- 所有其他行的日期(升序)
所以:
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
.