我在SQL Server中有一个具有以下架构的表:
CREATE TABLE [dbo].[MyTable]
(
[PatientId] [INT] NOT NULL,
[Timestamp] [DATETIME] NOT NULL,
[FiO2] [TINYINT] NULL
)
和以下查询,它们按5分钟的时差分组,并显示每个分组数据的FiO2和时间戳的平均值:
SELECT
AVG(FiO2) AS FiO2,
CAST(AVG(CAST([TimeStamp] AS FLOAT)) AS DATETIME) TimeStamp
FROM
MyTable
WHERE
PatientId = 97209520
GROUP BY
DATEADD(MINUTE, DATEDIFF(MINUTE,'2019-03-13 12:08:52.447',[TimeStamp]) / 5 * 5, 0)
以下是示例数据:
这是我的SQL查询的结果:
我已经使用过此linQ查询
var averagedData = loadedData.GroupBy(t => new {
t.PatientId,
TimeBracket = new DateTime(t.TimeStamp.Year, t.TimeStamp.Month, t.TimeStamp.Day, t.TimeStamp.Hour, t.TimeStamp.Minute,0).AddMinutes(5 - t.TimeStamp.Minute % 5)
})
.Select(p => new MonitorData{
PatientId = p.Key.PatientId,
FiO2 = (byte) p.Average(q => q.FiO2),
TimeStamp = new DateTime((long) p.Average(t => t.TimeStamp.Ticks), p.Key.TimeBracket.Kind)
})
.ToList();
由于某种原因,它返回5条记录,而不是4条具有不同计算值的记录。出于某种原因,它会将前两行分为一组,其余的分为四组,然后计算平均值。
答案 0 :(得分:0)
我无法找出如何作为完全本地的LINQ to SQL查询来执行此操作,但是如果进行分组,然后使用.AsEnumerable()
将结果拖入内存,则可以创建平均值...
这是LINQ,用于匹配问题中提供的查询的输出。它将每条记录四舍五入到最接近的5分钟,并保留秒和毫秒的数据。
var averagedData = loadedData
.GroupBy(t => new
{
t.PatientId,
TimeBracket = new DateTime(t.TimeStamp.Year, t.TimeStamp.Month, t.TimeStamp.Day, t.TimeStamp.Hour, (int)Math.Round(t.TimeStamp.Minute / 5.0) * 5, t.TimeStamp.Second, t.TimeStamp.Millisecond)
})
.Select(g => new MonitorData
{
PatientId = g.Key.PatientId,
FiO2 = (byte) g.Average(p => p.FiO2),
TimeStamp = new DateTime((long) g.Average(t => t.TimeStamp.Ticks), g.Key.TimeBracket.Kind)
}).ToList();
=================================
修改
此版本应与NHibernate一起使用,但这意味着将所有适当的患者行加载到内存中,然后进行计算:
var averaged =
table.Where(x => x.PatientId == 2)
.AsEnumerable()
.GroupBy(t => new
{
t.PatientId,
TimeBracket =
new DateTime(t.TimeStamp.Year, t.TimeStamp.Month, t.TimeStamp.Day, t.TimeStamp.Hour, t.TimeStamp.Minute,
0).AddMinutes(5 - t.TimeStamp.Minute % 5)
})
.Select(g => new MyTable
{
PatientId = g.Key.PatientId,
FiO2 = (byte) g.Average(p => p.FiO2),
TimeStamp = new DateTime((long) g.Average(t => t.TimeStamp.Ticks), g.Key.TimeBracket.Kind)
}).ToList();
=================================
这假设您在项目中拥有EntityFramework,并有权访问DbFunctions
:
var averaged =
table.Where(x => x.PatientId == 97209520)
.GroupBy(t => new {
t.PatientId,
t.TimeStamp,
TimeBracket = DbFunctions.AddMinutes(DbFunctions.CreateDateTime(t.TimeStamp.Year, t.TimeStamp.Month, t.TimeStamp.Day, t.TimeStamp.Hour, t.TimeStamp.Minute, 0), 5 - t.TimeStamp.Minute % 5).Value
})
.AsEnumerable()
.Select(g => new MyTable
{
PatientId = g.Key.PatientId,
FiO2 = (byte) g.Average(p => p.FiO2),
TimeStamp = new DateTime((long) g.Average(t => t.TimeStamp.Ticks), g.Key.TimeBracket.Kind)
}).ToList();