我尝试在SQL中执行此操作大约一个月,但我认为使用.NET linq可能更容易。
基本知识如下:
该查询应该返回日期范围内的数据,并返回播放器名称和播放器时间的串联列表。
仅当playEnd
在下一个玩家playStart
的30分钟之内时,才会发生串联。
所以,如果我有这样的数据:
Name PlayDate PlayStart PlayEnd
----------------------------------------------------
player1 | 10/8/2018 | 08:00:00 | 09:00:00
player2 | 10/8/2018 | 09:10:00 | 10:10:00
player3 | 10/9/2018 | 10:40:00 | 11:30:00
player4 | 10/11/2018 | 08:30:00 | 08:37:00
player5 | 10/11/2018 | 08:40:00 | 08:50:00
player6 | 10/12/2018 | 09:00:00 | 09:45:00
player7 | 10/12/2018 | 09:50:00 | 10:10:00
player8 | 10/12/2018 | 10:30:00 | 12:20:00
player1
和player2
的播放时间将串联在一起,例如:player1
,player2 = 8:00:00 - 10:10:00 for 10/8/2018
player3
仅是:player3 = 10:40:00 - 11:30:00 for 10/9/2018
player4
和player5
的播放时间将被合并为:player4
,player5 = 08:30:00 - 08:50:00 for 10/11/2018
player6
和player7
和player8
的播放时间将被合并为:player6
,player7
,player8 = 09:00:00 - 12:20:00 for 10/12/2018
我已经尝试过以多种方式修改查询,但是我只是不知道如何将一行数据与下一行数据进行比较,然后在需要时将这两行(或更多行)组合在一起。
var query = from pl in players
select new PlaySession
{
Name = pl.Name,
PlayDate = pl.PlayDate,
PlayStart = pl.PlayStartTime,
PlayEnd = pl.PlayEndTime
};
var grouped = query
.OrderBy(r => r.Name)
.ThenBy(r => r.PlayDate)
.ThenBy(r => r.PlayStart)
现在这是我感到困惑的地方:
我需要弄清楚以下几点:
如何比较各个行中的PlayDates
以确保它们是相同的日期,例如:row1.PlayDate == row2.PlayDate
如何将PlayEnd
的一行与接下来的PlayStart
的行进行比较,像这样:row2.PlayStart - row1.PlayEnd < 30 minutes
是否可以使用LINQ在各行之间比较值?
谢谢!
答案 0 :(得分:1)
根据我的关注,情况应该如下:
List<ViewModel> playersGroupList = Players.GroupBy(p => p.PlayDate).Select(group => new ViewModel
{
PlayDate = group.Key,
Names = String.Join("-", group.Select(g => g.Name).ToArray()),
PlayDuration = group.Select(g => g.PlayStart).First() + "-" + group.Select(g => g.PlayEnd).Last()
}).ToList();
这里ViewModel
如下:
public class ViewModel
{
public string PlayDate {get set;}
public string Names {get set;}
public string PlayDuration {get set;}
}
注意:满足点对点要求可能需要一些调整,但实际实现应如图所示。