我有一个表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,但是那样我将无法区分出哪一个不存在。最佳解决方案是什么?谢谢!
答案 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) ;
请注意,此版本还处理了严格增加的操作,这意味着不包括相等的计数。