通过附加约束在连续时间戳中获得最大差异?

时间:2017-03-01 10:04:18

标签: sql oracle

我有一张表items表示移动物品。其中,此表具有PK name,时间戳creation_time包含创建条目的时间,字符串type可以是start,{ {1}}或move end条目介于movestart之间。

表格的一部分可能如下所示:

end

我想得到的是连续时间戳的最大差异,其中第二个时间戳的类型不是name creation_time type _________________________________ i1 2017-03-01 10:00:01 start i1 2017-03-01 10:00:02 move i1 2017-03-01 10:00:08 move i1 2017-03-01 10:00:10 end i1 2017-03-01 10:00:31 start i1 2017-03-01 10:00:33 move i1 2017-03-01 10:00:37 end (我不关心start和{end之间的时间{1}})。

根据this SO question我提供了以下查询,但尚未考虑条目的类型:

start

我的问题是我现在不知道如何正确过滤该类型。根据我的理解,我必须从最里面的查询中获取类型,因为我关心第二个条目的类型,然后将select name, creation, next_creation, (next_creation-creation) difference from ( select name, creation, ( select min(creation) from items i2 where i2.name=i.name and i2.creation > i.creation ) as next_creation from items i ) where (next_creation-creation) is not null order by difference desc 添加到最外层查询的where子句中 - 但我不能从子查询中获取两个值,对吗?

编辑:我期望的结果如下:

and type<>'start'

如您所见,第一个name creation next_creation difference action i1 2017-03-01 10:00:02 2017-03-01 10:00:08 6s move i1 2017-03-01 10:00:33 2017-03-01 10:00:37 4s end [...] 和第二个end之间没有时间条目,这就是想要通过过滤类型来实现的目标。

例如,在第一个和最后一个条目之间没有条目,因为我想要连续条目之间的区别。

3 个答案:

答案 0 :(得分:2)

在编辑之前回答问题:

使用LAG analytic function

SELECT name,
       MAX( time_difference ) AS max_time_difference
FROM   (
  SELECT name,
         type,
         creation_time
           - LAG( creation_time ) OVER ( PARTITION BY name ORDER BY creation_time )
           AS time_difference
  FROM   items
)
WHERE type != 'start'
GROUP BY name;

<强>更新

为每组开始/结束项目(看起来是您期望的输出显示 - 因为它有多行)得到它:

SELECT name,
       creation_time,
       next_creation_time,
       next_creation_time - creation_time AS difference,
       type
FROM   (
  SELECT i.*,
         ROW_NUMBER() OVER (
           PARTITION BY name, start_group
           ORDER BY next_creation_time - creation_time DESC, creation_time ASC
         ) AS rn
  FROM   (
    SELECT name,
           type,
           creation_time,
           LEAD( creation_time ) OVER ( PARTITION BY name ORDER BY creation_time )
             AS next_creation_time,
           SUM( CASE type WHEN 'start' THEN 1 END )
             OVER( PARTITION BY name ORDER BY creation_time )
             AS start_group
    FROM   items
  ) i
  WHERE type != 'end'
)
WHERE rn = 1;

答案 1 :(得分:0)

根据我的理解。这必须包含列&#34; TYPE&#34;在子查询中,可以在内联视图中用作过滤器。希望它有所帮助。

SELECT name,
  creation,
  next_creation,
  (next_creation-creation) difference
FROM
  (SELECT name,
    creation,
    (SELECT MIN(creation)
    FROM items i2
    WHERE i2.name   =i.name
    AND I2.CREATION > I.CREATION
    ) AS NEXT_CREATION,
    type
  FROM items i
  )
WHERE (NEXT_CREATION-CREATION) IS NOT NULL
and type                       <> 'start'
ORDER BY difference DESC;

答案 2 :(得分:0)

如果您需要每个名称值的最大差异,那么类似的东西应该有效:

SELECT i1.NAME, MAX(i2.creation_time - i1.creation_time) difference
FROM items i1
INNER JOIN items i2 ON i1.name = i2.name AND i1.creation_time <= i2.creation_time
WHERE 'start' NOT IN (i1.type, i2.type)
GROUP BY i1.name;