我想查询一个包含多行的表,每行有timestamp
,数据间隔为十分钟。我想找到任何缺失数据的开头,这是没有timestamp
等于下一个十分钟间隔的地方,如下所示:
select a.[timestamp]
from [table] as a
where not exists (select 1
from [table] as b
where a.[id] = b.[id]
and b.[timestamp] = dateadd(mi, 10, a.[timestamp]))
order by a.[timestamp]
到目前为止我有这个,但是我没有看到如何构建查询以让我执行 b。[timestamp] = dateadd(mi,10,a。[timestamp])上面的查询:
Table tableAlias = null;
IList<DateTimeOffset> dateTimeOffsets = session.QueryOver(() => tableAlias)
.WithSubquery
.WhereNotExists(QueryOver.Of<Table>()
.Where(x => x.Id == tableAlias.Id)
.And(Restrictions.Eq(Projections.SqlFunction("addminutes",
NHibernateUtil.DateTimeOffset,
new[]
{
Projections.Property("Timestamp"),
Projections.Constant(10)
}),
<insert timestamp property again here>))
.Select(Projections.Constant(1)))
.Select(x => x.Timestamp)
.List<DateTimeOffset>();
我无法理解sqlfuntion部分的限制 - Nhibernate
我不会让我对sqlfunction和我的时间戳进行比较。
我希望我能够使用上面的代码走上正轨,但如果我完全没有尝试解决这个问题,请纠正我......
亲切的问候
答案 0 :(得分:2)
你走在正确的轨道上。您需要使用Restrictions.EqProperty
而不是Restrictions.Eq
,因为您要比较两个投影,而不是投影和常量值。
此外,您可以使用Expression
访问内部查询的TimeStamp
属性,而不是使用字符串。
以下代码适用于Sql Server 2008,但可能需要对其他数据库引擎进行一些调整:
Table a = null;
session.QueryOver<Table>(() => a)
.WithSubquery
.WhereNotExists(
QueryOver.Of<Table>()
.Where(t => t.Id == a.Id)
.And(Restrictions.EqProperty(
Projections.SqlFunction(
"addminutes",
NHibernateUtil.DateTimeOffset,
Projections.Constant(10),
Projections.Property(() => a.TimeStamp)),
Projections.Property(() => a.TimeStamp)))
.Select(Projections.Constant(1)))
.Select(t => t.TimeStamp)
.List<DateTimeOffset>();
哪个应生成以下SQL(至少在Sql Server 2008上):
SELECT this_.TimeStamp as y0_
FROM [Table] this_
WHERE not exists (SELECT 1 /* @p0 */ as y0_
FROM [Table] this_0_
WHERE this_0_.Id = this_.Id
and dateadd(minute, 10 /* @p1 */, this_.TimeStamp) = this_.TimeStamp)