2017-03-01 30 views
0

我有一个表items它代表移动的项目。其中,该表中有PK name,其中包含了创建条目和字符串type的时间,这可以是startmoveendmove条目来插图中startend时间戳creation_time通过额外的约束获得连续时间戳中最大的区别?

表的一部分可能看起来像这样:

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 

我想要得到的是连续的时间戳的最大区别(S),其中第二时间戳的类型不是start(我不照顾endstart之间的时间)。

基于this SO question我来用下面的查询这还没有考虑到的条目类型:

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 

我的问题是,我不知道如何正确地过滤了现在键入。据我的理解,我必须从最内层的查询中获取类型,因为我关心第二项的类型,然后将and type<>'start'添加到最外层查询的where子句中 - 但我无法从中获取两个值子查询,对吗?

编辑:我希望是这样的结果:

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和第二start之间的时间没有进入,这就是要通过过滤来实现方式。

例如,在第一次和最后一次输入之间的时间也没有输入,因为我想要连续输入之间的差异。

+0

请告诉我们查询的最终结果应该是什么样子等。 –

+0

您需要每个名称值的最大差异? – Mikhail

回答

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; 
+0

谢谢!该功能正是我所搜索的功能,而且我的建立的查询速度更快。 –

0

根据我的理解。这必须包含子查询中的“TYPE”列,可用作Inline View中的过滤器。希望能帮助到你。

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; 
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;