PostgreSQL - 根据条件为每行分配值

时间:2014-04-07 08:45:41

标签: database postgresql

我有下表。

date    label   time
2014-04-06  A   12:05:56
2014-04-06  A   23:02:32
2014-04-06  B   8:39:25
2014-04-06  B   12:36:37
2014-04-06  C   12:20:43
2014-04-06  C   12:56:44
2014-04-06  D   20:52:22
2014-04-06  E   22:25:30
2014-04-06  F   12:16:15
2014-04-06  F   12:31:09
2014-04-06  F   17:12:06
2014-04-06  G   7:48:32
2014-04-06  H   17:58:11
2014-04-05  I   12:05:56
2014-04-05  I   20:02:32
2014-04-05  I   23:57:32
2014-04-05  J   12:36:37
2014-04-05  K   12:20:43
2014-04-05  L   12:56:44
2014-04-05  M   20:52:22
2014-04-05  M   22:25:30
2014-04-05  N   12:16:15
2014-04-05  O   12:31:09
2014-04-05  O   17:12:06
2014-04-05  P   7:48:32
2014-04-05  Q   17:58:11
2014-04-06  R   1:05:56
2014-04-06  R   5:02:32
2014-04-06  R   8:39:25
2014-04-06  R   12:36:37
2014-04-06  S   12:20:43
2014-04-06  S   12:56:44
2014-04-06  S   20:52:22
2014-04-06  T   22:25:30
2014-04-06  U   12:16:15
2014-04-06  V   12:31:09
2014-04-06  W   3:48:32
2014-04-06  W   7:48:32
2014-04-06  W   17:58:11

我尝试使用此输出创建视图。

date    label   time    status
2014-04-06  A   12:05:56    Repeat
2014-04-06  A   23:02:32    Unique
2014-04-06  B   8:39:25 Repeat
2014-04-06  B   12:36:37    Unique
2014-04-06  C   12:20:43    Repeat
2014-04-06  C   12:56:44    Unique
2014-04-06  D   20:52:22    Unique
2014-04-06  E   22:25:30    Unique
2014-04-06  F   12:16:15    Repeat
2014-04-06  F   12:31:09    Repeat
2014-04-06  F   17:12:06    Unique
2014-04-06  G   7:48:32 Unique
2014-04-06  H   17:58:11    Unique
2014-04-05  I   12:05:56    Repeat
2014-04-05  I   20:02:32    Repeat
2014-04-05  I   23:57:32    Unique
2014-04-05  J   12:36:37    Unique
2014-04-05  K   12:20:43    Unique
2014-04-05  L   12:56:44    Unique
2014-04-05  M   20:52:22    Repeat
2014-04-05  M   22:25:30    Unique
2014-04-05  N   12:16:15    Unique
2014-04-05  O   12:31:09    Repeat
2014-04-05  O   17:12:06    Unique
2014-04-05  P   7:48:32 Unique
2014-04-05  Q   17:58:11    Unique
2014-04-06  R   1:05:56 Repeat
2014-04-06  R   5:02:32 Repeat
2014-04-06  R   8:39:25 Repeat
2014-04-06  R   12:36:37    Unique
2014-04-06  S   12:20:43    Repeat
2014-04-06  S   12:56:44    Repeat
2014-04-06  S   20:52:22    Unique
2014-04-06  T   22:25:30    Unique
2014-04-06  U   12:16:15    Unique
2014-04-06  V   12:31:09    Unique
2014-04-06  W   3:48:32 Repeat
2014-04-06  W   7:48:32 Repeat
2014-04-06  W   17:58:11    Unique

status列的标准将如下所示。

我希望根据导出状态列的labeltime列条件循环每一行。

假设第一行标签=第二行标签,第二行和第一行的时间差大于24:00:00,则必须为是,否则为否。

我在excel中这样做。

=IF(AND(B2=B3,C3-C2>1),"Yes","No")

我是PostgreSQL和数据库的新手。

任何建议或帮助都会对此有所帮助。

提前致谢。

1 个答案:

答案 0 :(得分:3)

注意:

  1. 如果您的公式实际上在Excel中有效,那么您在单元格中存储日期,而不是时间。
  2. 对于D, E,我不明白,如果前一行没有相同的标签,这应该如何返回'是'
  3. 您必须在表格中添加一些带ID的列(!)。虽然Excel在工作表中保持相同的行顺序(除非您明确地更改它),但PostgreSQL却没有。因此,如果你真的只有列时间的时间,那么你就无法获得与表中相同的行顺序,导致完全错误的结果。
  4. 如果您使用的是版本8.4,那么您的链接是正确的,但如果您使用当前documentation
  5. 会更好

    数据:

    drop table if exists tmp.test;
    
    create table tmp.test (id int, ddate date, label varchar, ttime time);
    
    insert into tmp.test values
    
    (1, '2014/6/4','A','12:05:56'),
    (2, '2014/6/4','A','23:02:32'),
    (3, '2014/6/4','B','8:39:25'),
    (4, '2014/6/4','B','12:36:37'),
    (5, '2014/6/4','C','12:20:43'),
    (6, '2014/6/4','C','12:56:44'),
    (7, '2014/6/4','D','20:52:22'),
    (8, '2014/6/4','E','22:25:30'),
    (9, '2014/6/4','F','12:16:15'),
    (10, '2014/6/4','F','12:31:09'),
    (11, '2014/6/4','F','7:12:06'),
    (12, '2014/6/4','G','7:48:32'),
    (13, '2014/6/4','H','17:58:11');
    

    查询:

    select
      id, 
      ddate,
      label,
      ttime,
      case when (lag(ttime) over(partition by label order by id))::interval
            + ttime::interval > interval '24 hours' then 'yes' else 'no' end
      -- ,(lag(ttime) over(partition by label order by ttime))::interval + ttime::interval
    from
      tmp.test
    

    说明:

    1. lag函数将在给定分区的前一行中获取值。在我们的例子中,分区由label。
    2. 定义
    3. 强制转换操作符::会将time类型更改为interval,因此我们可以添加时间并获得超过24小时。
    4. 我们将总时间间隔为24小时,并显示一个不错的标签yesno
    5. 更新

      select
        id, 
        ddate,
        label,
        ttime,
        case when lead(label) over(partition by label order by id) is null then 'no' else 'yes' end
      from
        tmp.test