我在建立一个查询时遇到了一些麻烦,该查询会将我的商品根据是否存在于一个月中的时间分组到每月范围内。我正在使用PostgreSQL。
例如,我有一个数据表,如下所示:
Name Period(text)
Ana 2010/09
Ana 2010/10
Ana 2010/11
Ana 2010/12
Ana 2011/01
Ana 2011/02
Peter 2009/05
Peter 2009/06
Peter 2009/07
Peter 2009/08
Peter 2009/12
Peter 2010/01
Peter 2010/02
Peter 2010/03
John 2009/05
John 2009/06
John 2009/09
John 2009/11
John 2009/12
我希望结果查询是这样的:
Name Start End
Ana 2010/09 2011/02
Peter 2009/05 2009/08
Peter 2009/12 2010/03
John 2009/05 2009/06
John 2009/09 2009/09
John 2009/11 2009/12
有什么办法可以做到这一点?
最佳答案
这是一个汇总问题,但有一个转折点-您需要为每个名称定义相邻月份的分组。
假设一个给定的名称月份从未出现过多次,则可以通过为每个期间分配一个“月份”数字并减去一个连续的数字来做到这一点。连续几个月,这些值将是一个常数。
select name, min(period), max(period)
from (select t.*,
(cast(left(period, 4) as int) * 12 + cast(right(period, 2) as int) -
row_number() over (partition by name order by period)
) as grp
from names t
) t
group by grp, name;
Here是说明此问题的SQL Fiddle。
注意:重复也不是真正的问题。您可能会使用
dense_rank()
而不是row_number()
。