检测postgres表中的一系列递减值

时间:2015-08-10 16:04:25

标签: sql postgresql

我有一个表格,其中包含一系列日期,客户ID和整数,每周更新所有ID的新日期和整数值。

我希望能够编写一个查询来检测最近的三个值是否按降序排列,并为每个ID返回TRUE或FALSE。

所以,对于表:

ID | Weekending | Value
1  | 2015-07-15 | 5
2  | 2015-07-15 | 23
1  | 2015-07-08 | 7
2  | 2015-07-08 | 21
1  | 2015-07-01 | 9
2  | 2015-07-01 | 24

我想要一个为ID:1返回TRUE的查询,因为三个连续值下降,但ID为2时为FALSE,因为值增加了。

3 个答案:

答案 0 :(得分:3)

不确定性能,但使用这样的lag窗口函数应该有效:

select *, 
    case when 
        value < lag(value, 1) over (partition by id order by weekending) 
    and value < lag(value, 2) over (partition by id order by weekending) 
    then 'True' else 'False' end
from t
order by id, weekending desc;

这会将行1 | 2015-07-15 | 5标记为true,将所有其他行标记为false。

Sample SQL Fiddle

要只获取每个ID的最后一行,您可以执行此操作:

select ID, Weekending, Value, decrease 
from (
    select *, 
       case when 
           value < lag(value, 1) over (partition by id order by weekending) 
       and value < lag(value, 2) over (partition by id order by weekending) 
       then 'True' else 'False' end as decrease,
       row_number() over (partition by id order by weekending desc) as r
    from t
) src 
where r = 1;

会给你一个像:

的结果
ID  Weekending  Value   decrease
1   2015-07-15  5       True
2   2015-07-15  23      False

答案 1 :(得分:0)

如果您只能根据周末值选择相关记录(假设所有ID都有最近一周的记录),您可以在数组中选择值并使用数组方法检测值是下降还是不:

with cte_values as (
  select id,
         array_agg(value order by weekending) value_array
  from   my_table
  where  weekending >= <add something to select the relevant weeks>)
select id
       case
         when value_array[2] < value_array[1] and
              value_array[3] < value_array[2]
         then true
         else false
       end is_ascending
from cte_values

未检查语法

答案 2 :(得分:0)

SELECT DISTINCT ON (id) 
id, week,val,val1,val2, val< val1 AND val1 < val2 as decreases
FROM (
 SELECT id,week,val, 
 lag(val,-1,10000) OVER w1 AS val1, 
 lag(val,-2,10001) OVER w1 AS val2 
 FROM TAB 
 WINDOW w1 AS (PARTITION BY id ORDER BY week DESC)
 ORDER BY ID,week  DESC) 
AS X

这假设10000和10001是非常大的值&#34; (真值总是低于该值),并且您对严格递减序列感兴趣。

例如,对于数据

       id    week        val
        1  2015-07-15      5
        1  2015-07-08      7
        1  2015-07-01      9
        1  2015-06-28    121
        1  2015-06-15      2 
        2  2015-07-15     23
        2  2015-07-08     21
        2  2015-07-01     24
        3  2015-07-15     20
        3  2015-07-08     21
        4  2015-07-15     30
        4  2015-07-08     21
        5  2015-07-08    210

这给出了

   id     week        val     val1     val2   decreases
    1   2015-07-15      5        7        9      t
    2   2015-07-15     23       21       24      f
    3   2015-07-15     20       21    10001      t
    4   2015-07-15     30       21    10001      f
    5   2015-07-08    210    10000    10001      t