3

複数の行を持つテーブルにクエリを実行したいと思います。それぞれの行にtimestampは 10 分間隔でデータが送信されます。timestamp次のように、次の 10 分間隔に等しくない欠落データの始まりを見つけたいと思います。

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 部分の制限に頭を悩ませることができません - Nhibernatesqlfunction とタイムスタンプの比較をさせてくれません。

上記のコードで正しい軌道に乗っていることを願っていますが、これを解決しようとして完全にずれている場合は修正してください...

敬具

4

1 に答える 1

3

あなたは正しい軌道に乗っています。投影と定数値ではなく、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)
于 2012-06-19T15:10:09.983 に答える