且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-02-05 09:33:08

注意:


  1. 如果您的公式实际上在Excel中有效,则表示您将日期存储在单元格中,而不是时间中。

  2. 对于 D,E ,我不明白,当上一行没有相同标签时,应该如何返回是

  3. 您必须在表中添加ID列(!)。尽管Excel在工作表中保留相同的行顺序(除非您明确更改了它),但PostgreSQL却没有。因此,如果您确实只有列时间,那么就不可能获得与表中相同的行顺序,从而导致结果完全错误。

  4. 如果如果使用的是8.4版,则您的链接是正确的,但是如果使用当前的文档

  1. If your formula actually works in Excel, than you have stored dates in cells, not time.
  2. For D, E, I do not understand, how this should return 'yes' when previous row does not have same label
  3. You have to add some column with ID to your table (!). While Excel keeps the same order of rows in sheet (unless you change it explicitly), PostgreSQL does not. Thus, if you really have only time in column time, than there is no way you can get same order of rows as you have in your table, leading in completely incorrect results.
  4. If your are using version 8.4 then your link is correct, however it would be better if you use current documentation

数据:

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 函数将在给定分区的上一行中获取值。在我们的例子中,分区由标签定义。

  2. 广播运算符 :: 将更改时间输入 interval ,这样我们可以增加时间并获得超过24小时的时间。

  3. 我们将总时间与24小时进行了比较间隔并显示一个漂亮的标签

  1. lag function will get value in previous row for given partition. In our case, partition is defined by label.
  2. cast operator :: will change time type into interval, so we can add time and get more than 24 hours.
  3. We compare total to 24 hours interval and display a nice label yes or no.

更新:

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