根据id和时间戳差异创建唯一ID

时间:2014-03-13 07:58:34

标签: sql postgresql postgresql-9.1 postgresql-9.2

我有一张包含以下信息的表格:

CREATE TABLE TABLE1(
    col1 bigint,
    col2 TIMESTAMP,
    col3 integer
)

一些样本数据是

28564635; "2014-03-11 07:02:16+03"; 51
28564635; "2014-03-11 07:06:25+03"; 52
28564635; "2014-03-11 07:13:38+03"; 53
28564635; "2014-03-11 07:21:19+03"; 56
28564636; "2014-03-11 07:01:16+03"; 31
28564636; "2014-03-11 07:06:16+03"; 29
28564636; "2014-03-11 07:37:16+03"; 30
28564636; "2014-03-11 07:39:16+03"; 31

值按col1和col2按升序排序。现在要求是根据条件在末尾附加计算列:

  • 第一行被赋予id 1
  • 从第2行开始,如果当前col1 =前一行的col1和当前col2 - 前一个col2< 30然后id将为1(与第1行相同),否则将id增加1。

因此输出将类似于

28564635; "2014-03-11 07:02:16+03"; 51; 1
28564635; "2014-03-11 07:06:25+03"; 52; 1
28564635; "2014-03-11 07:13:38+03"; 53; 1
28564635; "2014-03-11 07:21:19+03"; 56; 1
28564636; "2014-03-11 07:01:16+03"; 31; 2
28564636; "2014-03-11 07:06:16+03"; 29; 2
28564636; "2014-03-11 07:37:16+03"; 30; 3
28564636; "2014-03-11 07:39:16+03"; 31; 3

如何在不使用游标的情况下在SQL查询中实现此目的。

1 个答案:

答案 0 :(得分:3)

SQLFiddle

数据:

-- drop table if exists table1;

create table table1(
    col1 bigint,
    col2 timestamp,
    col3 integer
);

insert into table1 (col1, col2, col3) values
   (28564635, '2014-03-11 07:02:16+03', 51),
   (28564635, '2014-03-11 07:06:25+03', 52),
   (28564635, '2014-03-11 07:13:38+03', 53),
   (28564635, '2014-03-11 07:21:19+03', 56),
   (28564636, '2014-03-11 07:01:16+03', 31),
   (28564636, '2014-03-11 07:06:16+03', 29),
   (28564636, '2014-03-11 07:37:16+03', 30),
   (28564636, '2014-03-11 07:39:16+03', 31)
;

查询:

select
  *,
  sum(test) over (order by col1, col2) as rn
from (
  select
    *,
    (not 
       coalesce(extract(epoch from col2 
       - lag(col2) over(partition by col1 order by col2))/60.0 < 30, false)
    )::int as test
  from
    table1
  ) a

结果:

28564635;2014-03-11 07:02:16;51;1;1
28564635;2014-03-11 07:06:25;52;0;1
28564635;2014-03-11 07:13:38;53;0;1
28564635;2014-03-11 07:21:19;56;0;1
28564636;2014-03-11 07:01:16;31;1;2
28564636;2014-03-11 07:06:16;29;0;2
28564636;2014-03-11 07:37:16;30;1;3
28564636;2014-03-11 07:39:16;31;0;3

说明:

  1. 获取当前col2
  2. 的上一个col1
  3. 从先前col2中减去当前col2并计算分钟数
  4. 测试是否少于30分钟
  5. 将结果合并到false(对于之前没有col2的行
  6. 注意:前一个标记每个第一行(col1)和每个行的差异&gt;使用false
  7. 30分钟
  8. 取消所有内容 - 对于我们要增加计数器的所有行,我们得到true
  9. 将布尔值转换为整数(true=1false=0
  10. 在外部查询中计算我们的测试的运行总和,按col1col2
  11. 排序