我在建立一个查询时遇到了一些麻烦,该查询会将我的商品根据是否存在于一个月中的时间分组到每月范围内。我正在使用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()

10-04 10:42
查看更多