判断表中的条目是否正在增加

时间:2019-01-20 17:46:13

标签: sql postgresql

我有一个表temp(个人文本,year int,count int)。它存储

person, year, count
("a",2009,1),
("a",2010,2), 
("a",2011,3), 
("a",2012,4),
("b",2010,1),
("b",2011,2),
("b",2012,3), 
("c",2011,1),
("d",2009,4),
("d",2010,4), 
("d",2011,4), 
("d",2012,4),
("e",2009,1),
("e",2010,2),
("e",2012,4)

我应该告诉我们,从2009年到2012年,对于哪个人的计数严格增加,计数始终是一个正整数。对于给定的表,输出将为“ a”和“ b”。请注意,“ b”也严格增加,因为它在2009年的计数为0(我知道上面写出计数必须为正数有点奇怪,现在我说的是2009年该计数为0,但这只是给定的像问题中那样)。

预期产量:-在给定的表中,a从2009-2012年严格增加。这很酷。对于b,它缺少2009年,但我们将其设为零(准确地说,名字是作者的名字,计数是他们发表的论文的数量-我们必须找到2010年发表的论文比2009年多的那些作者,在2011年比在2010年,而在2012年比在2011年,那么让count = 0确实有意义)。因此,对于b,2009为0。因此,序列为0、2、3、4-严格递增。由于2009和10的计数均为零,因此不应打印c。同样,d不应打印,因为其计数是恒定的。不应打印e,因为取0后,其顺序变为1、2、0、4。因此,a和b应该是唯一的输出。

我的尝试:-我尝试使用滞后函数,但是存在一个问题,因为它无法区分2009年是否存在。我也可以在其中使用count,但是那样我将无法区分出哪一个不存在。最佳解决方案是什么?谢谢!

3 个答案:

答案 0 :(得分:1)

使用与表左连接的generate_series()来获取完整的counts数据:

select year, person, coalesce(count, 0) as count
from generate_series(2009, 2012) as year
cross join (
    select distinct person
    from temp
    ) p
left join temp using(year, person)
order by 2, 1

 year | person | count 
------+--------+-------
 2009 | a      |     1
 2010 | a      |     2
 2011 | a      |     3
 2012 | a      |     4
 2009 | b      |     0
 2010 | b      |     1
 2011 | b      |     2
 2012 | b      |     3
 2009 | c      |     0
 2010 | c      |     0
 2011 | c      |     1
 2012 | c      |     0
 2009 | d      |     4
 2010 | d      |     4
 2011 | d      |     4
 2012 | d      |     4
 2009 | e      |     1
 2010 | e      |     2
 2011 | e      |     0
 2012 | e      |     4
(20 rows)

在结果上使用array_agg()来找到满足条件的persons

select person, array_agg(count order by year) as counts
from (
    select person, year, coalesce(count, 0) as count
    from generate_series(2009, 2012) as year
    cross join (
        select distinct person
        from temp
        ) p
    left join temp using(year, person)
    ) s
group by person
having  array_agg(distinct count order by count) = array_agg(count order by year)

 person |  counts 
--------+-----------
 a      | {1,2,3,4}
 b      | {0,1,2,3}
(2 rows)    

答案 1 :(得分:0)

编辑:

基于新数据和更详细的逻辑,这应该可以工作(基于蒂姆的查询):

 37    printf("status = (%#02x)\n", (status |= 0xC0));
 38    printf("status = (%#04x)\n", (status |= 0xC0));
 39    printf("status = (%#04x)\n", 0x0f);
 40    printf("status = (%#02x)\n", 0x0f);
status = (0xc0)
status = (0xc0)
status = (0x0f)
status = (0xf)

答案 2 :(得分:0)

我喜欢klin的解决方案,但您不需要generate_series()cross join

select person
from temp t
where year between 2009 and 2012
group by person
having (count(*) = 4 and count(distinct count) = 4 or
        count(*) = 3 and min(year) = 2010 and count(distinct count) = 3
       ) and
       array_agg(count order by count) = array_agg(count order by year) ;

请注意,此版本还处理了严格增加的操作,这意味着不包括相等的计数。