3

我想查询一个有多行的表,每行都有一个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 和我的时间戳。

我希望我使用上面的代码走在正确的轨道上,但是如果我完全不打算解决这个问题,请纠正我......

亲切的问候

4

1 回答 1

3

你在正确的轨道上。您需要使用Restrictions.EqProperty而不是,Restrictions.Eq因为您正在比较两个投影而不是投影和常数值。

此外,您可以使用 anExpression来访问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)
于 2012-06-19T15:10:09.983 回答