Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL 2008帮助:根据引用ID、日期时间和日期时间值之间的间隔比较当前行和上一行_Sql_Events_Rows_Identifier_Series - Fatal编程技术网

SQL 2008帮助:根据引用ID、日期时间和日期时间值之间的间隔比较当前行和上一行

SQL 2008帮助:根据引用ID、日期时间和日期时间值之间的间隔比较当前行和上一行,sql,events,rows,identifier,series,Sql,Events,Rows,Identifier,Series,我正试图根据一些逻辑运算符为事件分配一个ID 我的数据由一个参考字段(VC,例如region.town.property样式)、DateTime(DT、dd/mm/yyyy hh:mm:ss)和以1秒间隔记录的值(十进制)组成。原始数据表中有大约300000000条记录 对于数据表示的一个例子,考虑值字段来表示水流入标准水箱厕所。通常(以1秒的记录间隔)流量为零。在某个时刻,有人会冲洗马桶,在马桶重新注满水之前,马桶会清空水箱中的水来冲洗马桶。重新注满水箱所需的时间取决于水箱的水压和容量。当我提

我正试图根据一些逻辑运算符为事件分配一个ID

我的数据由一个参考字段(VC,例如region.town.property样式)、DateTime(DT、dd/mm/yyyy hh:mm:ss)和以1秒间隔记录的值(十进制)组成。原始数据表中有大约300000000条记录

对于数据表示的一个例子,考虑值字段来表示水流入标准水箱厕所。通常(以1秒的记录间隔)流量为零。在某个时刻,有人会冲洗马桶,在马桶重新注满水之前,马桶会清空水箱中的水来冲洗马桶。重新注满水箱所需的时间取决于水箱的水压和容量。当我提到一个“事件”时,我指的是从水箱开始重新注满(即系列中的第一个非零值)到水箱注满(即系列中的最后一个非零值)之间的时间。我正在尝试为每个“事件”分配一个ID

我使用excel电子表格设置了一个测试用例,以便检查我的逻辑假设,但现在我正努力将这些假设转换为SQL(使用SQL Server 2008 R2)

我的第一步是只选择具有非零值的记录(使用0)

下面是我的excel公式,这是我试图将SQL查询建立在的基础上的,还有示例数据和所需的“ID”字段。
=如果(和(B3=B2,天(C3)=天(C2),月(C3)=月(C2),年(C3)=年(C2),时间(小时(C3),分钟(C3),秒(C3))=时间(小时(C2),分钟(C2),秒(C2)+1))=真,A2,A2+1)

这里的逻辑是检查当前行和前一行,以确定这些值是否属于同一站点(参考值_VC,单元格参考值B3和B2),并且两个DateTime_DT字段(单元格C3和C2)之间的时间差正好是1秒。如果满足条件,则从上一行获取ID。如果条件失败,则新的ID系列将开始向前面的ID添加1

    ID  Reference_VC    DateTime_DT Value_DEC
    1   a.b.c   29/07/2000 00:43:30 0.2236
    1   a.b.c   29/07/2000 00:43:31 0.2045
    2   a.b.c   29/07/2000 00:43:35 0.2674
    2   a.b.c   29/07/2000 00:43:36 0.2806
    3   a.b.c   29/07/2000 00:43:40 0.3716
    4   d.e.f   29/07/2000 00:42:35 0.2001
    4   d.e.f   29/07/2000 00:42:36 0.2231
    4   d.e.f   29/07/2000 00:42:37 0.2604
    4   d.e.f   29/07/2000 00:42:38 0.3729
    4   d.e.f   29/07/2000 00:42:39 0.2358
    5   d.e.f   29/07/2000 00:42:45 0.2599
    5   d.e.f   29/07/2000 00:42:46 0.2099
    6   g.h.i   29/07/2000 01:13:42 0.3129
    7   g.h.i   29/07/2000 01:13:42 0.2313
    8   g.h.i   29/07/2000 01:13:42 0.2966
    9   g.h.i   29/07/2000 01:13:42 0.3611
    10  g.h.i   29/07/2000 01:13:42 0.2293
    11  g.h.i   29/07/2000 01:13:42 0.3889
任何帮助都将不胜感激

谢谢


Mike

此查询生成您所说的要查找的结果。我正在使用
@t
代替原来的表1:


您需要什么输出?你能根据你展示的相同样本数据来做吗?嗨,达米安,谢谢你看这个。我想要的输出是示例数据中的“ID”列。我的原始数据由参考数据、日期时间数据和值数据组成,正如我对较小示例数据集所希望的那样,我现在正在较大的数据集上运行查询,但我不希望它很快完成。非常感谢您的帮助,虽然我可以看到查询中的每个步骤都做了些什么,但我不能说我完全理解查询的工作原理!这一定很神奇。再次感谢,Mike@Lechuza-不幸的是,必须进行日期计算排除了使用索引的任何可能帮助。如果这是一个大数据集和/或一个公共查询要运行,我会考虑将一个索引的计算列添加到存储<代码> DATEADD(第二,1,DATEMEMEDT)的表中。这样就可以避免在查询本身中使用
DATEADD
s,从而提供更好的性能。再次感谢您的帮助Damian。在我不得不关闭机器之前,查询运行了大约40个小时,没有结果。我将尝试按照您的建议添加computed列,看看这是否会加快速度。再次感谢!
;With Ordered as (
    select ROW_NUMBER() OVER (PARTITION BY Reference_VC
                              ORDER BY DateTime_DT) as rn,*
    from @t
), Islands as (
    select o.Reference_VC, o.rn as RnStart, o.rn as RnEnd,
           o.DateTime_DT as dtStart, o.DateTime_DT as dtEnd
    from Ordered o
        left join
        Ordered o_not
        on o.Reference_VC = o_not.Reference_VC and
           o.rn = o_not.rn + 1 and
           o.DateTime_DT = DATEADD(second,1,o_not.DateTime_DT)
    where
        o_not.rn is null
    union all
    select
        i.Reference_VC,i.RnStart,o.rn,i.dtStart,o.DateTime_DT
    from Islands i
        inner join
        Ordered o
            on
                i.Reference_VC = o.Reference_VC and
                i.RnEnd = o.rn - 1 and
                i.dtEnd = DATEADD(second,-1,o.DateTime_DT)
), FinalIslands as (
    select Reference_VC,RnStart,dtStart,
           MAX(rnEnd) as rnEnd,MAX(dtEnd) as dtEnd,
           ROW_NUMBER() OVER (Order BY Reference_VC,RnStart) as ID
    from Islands i
    group by Reference_VC,RnStart,dtStart
)
select
    fi.ID,t.*
from
    FinalIslands fi
        inner join
    @t t
        on
            fi.Reference_VC = t.Reference_VC and
            fi.dtStart <= t.DateTime_DT and
            fi.dtEnd >= t.DateTime_DT
declare @t table (Reference_VC varchar(5) not null,
                  DateTime_DT datetime not null,
                  Value_DEC decimal(10,9) not null)
insert into @t(Reference_VC,DateTime_DT,Value_DEC) values
('a.b.c','2000-07-29T00:43:30',0.2236),
('a.b.c','2000-07-29T00:43:31',0.2045),
('a.b.c','2000-07-29T00:43:35',0.2674),
('a.b.c','2000-07-29T00:43:36',0.2806),
('a.b.c','2000-07-29T00:43:40',0.3716),
('d.e.f','2000-07-29T00:42:35',0.2001),
('d.e.f','2000-07-29T00:42:36',0.2231),
('d.e.f','2000-07-29T00:42:37',0.2604),
('d.e.f','2000-07-29T00:42:38',0.3729),
('d.e.f','2000-07-29T00:42:39',0.2358),
('d.e.f','2000-07-29T00:42:45',0.2599),
('d.e.f','2000-07-29T00:42:46',0.2099),
('g.h.i','2000-07-29T01:13:42',0.3129),
('g.h.i','2000-07-29T01:13:42',0.2313),
('g.h.i','2000-07-29T01:13:42',0.2966),
('g.h.i','2000-07-29T01:13:42',0.3611),
('g.h.i','2000-07-29T01:13:42',0.2293),
('g.h.i','2000-07-29T01:13:42',0.3889)