从开始日期和结束日期跨越天的数据创建趋势数据
本文关键字:数据 日期 创建 跨越 开始 结束 | 更新日期: 2023-09-27 18:31:40
我正在使用C#,NHibernate,Fluent NHibernate和LINQ(存储库模式)。
关于我想做什么的虚构故事
假设我有一个停车位,所以我有一辆车从日期到日期租用一个停车位。这将成为数据库中的一个条目。
我想找出过去 30 天内每天有多少辆汽车。因此,可以在趋势图中使用的数据。
描述
我拥有的是数据库中的条目,如下所示:
Entry:
--------
ID
StartDate
EndDate
我需要找出在一段时间内(比如last 30 days
)有多少条目each day
。
如果我在数据库中说了这些数据:
ID | Start | End
---|------------|----------
1 | 2013-01-01 | 2013-01-01
2 | 2013-01-02 | 2013-01-02
3 | 2013-01-02 | 2013-01-03 <-- NOTICE
4 | 2013-01-03 | 2013-01-03
5 | 2013-01-03 | 2013-01-05 <-- NOTICE
6 | 2013-01-04 | 2013-01-05
我的日期范围2013-01-01
到2013-01-05
。
我除了结果:
Date | Value | Entry IDs (not part of the result, only here for clarity)
-----------|-------|-----------
2013-01-01 | 1 | 1
2013-01-02 | 2 | 2 3
2013-01-03 | 3 | 3 4 5
2013-01-04 | 2 | 5 6
2013-01-05 | 2 | 5 6
我目前只按startdate
分组然后获取数字,但现在这是无效的,因为这个新要求是随enddate
一起添加的。
我可以在该范围内每天做一个,尝试找到与之匹配的条目,但我认为这对数据库或 Web 服务来说太昂贵了。
建议?
也许是这样的:
var start = new DateTime(2013, 01, 01);
var end = DateTime(2013, 01, 05);
var q = d.Query()
.Where(x =>
x.Date >= start
&& end >= x.Date) // there you filter for range
.GroupBy(x => x.Date); // use .Day to group by day
开始时间和结束时间包括在内。
编辑
我发现了这个(实际上我在我的项目中有一个类似的案例):
var start = new DateTime(2013, 1, 1);
var end = new DateTime(2013, 1, 5);
var current = start;
var ranges = new List<DateTime>();
while (current <= end)
{
ranges.Add(current);
current = current.AddDays(1);
}
var res = ranges.Select(x => new
{
date = x,
entries = entries.Where(e => e.Start <= x && x <= e.End).ToList()
}).ToList();
尝试测试它,也许您可以适应您的情况(请注意,过滤从日期范围开始)。
可以使用适用于 .NET 的时间段库来计算趋势数据:
// ----------------------------------------------------------------------
class CarPeriod : DayTimeRange
{
// --------------------------------------------------------------------
public CarPeriod( int id, DateTime start, DateTime end ) :
this( id, start, end.Date.AddDays( 1 ).Subtract( start.Date ).Days )
{
} // CarPeriod
// --------------------------------------------------------------------
public CarPeriod( int id, DateTime start, int days ) :
base( start.Year, start.Month, start.Day, days )
{
Id = id;
} // CarPeriod
// --------------------------------------------------------------------
public int Id { get; private set; }
} // class CarPeriod
// ----------------------------------------------------------------------
[Sample( "DaysTrendData" )]
public void DaysTrendData()
{
// periods
ITimePeriodCollection carPeriods = new TimePeriodCollection();
carPeriods.Add( new CarPeriod( 1, new DateTime( 2013, 1, 1 ), new DateTime( 2013, 1, 1 ) ) );
carPeriods.Add( new CarPeriod( 2, new DateTime( 2013, 1, 2 ), new DateTime( 2013, 1, 2 ) ) );
carPeriods.Add( new CarPeriod( 3, new DateTime( 2013, 1, 2 ), new DateTime( 2013, 1, 3 ) ) );
carPeriods.Add( new CarPeriod( 4, new DateTime( 2013, 1, 3 ), new DateTime( 2013, 1, 3 ) ) );
carPeriods.Add( new CarPeriod( 5, new DateTime( 2013, 1, 3 ), new DateTime( 2013, 1, 5 ) ) );
carPeriods.Add( new CarPeriod( 6, new DateTime( 2013, 1, 4 ), new DateTime( 2013, 1, 5 ) ) );
Days testDays = new Days( new DateTime( 2013, 1, 1 ), 5 );
foreach ( Day testDay in testDays.GetDays() )
{
Console.Write( "Day: " + testDay + ": " );
foreach ( CarPeriod carPeriod in carPeriods )
{
if ( carPeriod.IntersectsWith( testDay ) )
{
Console.Write( carPeriod.Id + " " );
}
}
Console.WriteLine();
}
} // DaysTrendData