与子句外部的列一起分组

Vis*_*han 5 sql postgresql group-by

我有一个SQL表如下

    id    |date_accessed     
----------+------------
     1    | 16/10/2014
     1    | 28/10/2014
     1    | 25/11/2014
     1    | 16/12/2014
     2    | 30/09/2014
     2    | 03/10/2014
     2    | 17/10/2014
     2    | 03/01/2015
Run Code Online (Sandbox Code Playgroud)

我需要按月和年对数据进行分组,但是我也想知道自用户第一次访问系统以来有多少个月的时间。

    id    |   month    |   year     |   length_in_month
----------+------------+------------+-------------------
     1    |    10      |   2014     |          1
     1    |    11      |   2014     |          2     
     1    |    12      |   2014     |          3
     2    |    09      |   2014     |          1
     2    |    10      |   2014     |          2
     2    |    01      |   2015     |          5
Run Code Online (Sandbox Code Playgroud)

我的查询如下

select 
    id, 
    Extract(MONTH from "date_accessed") as month, 
    Extract(year from "date_accessed") as year 
from 
    exampleTable 
group by 
    1, 2, 3 
order by 
    1, 3, 2 
Run Code Online (Sandbox Code Playgroud)

但是我无法min(date_accessed)通过分组进行访问来获取length_in_month列的长度。

有解决方案吗?

Kau*_*yak 2

我使用函数来确定首次访问月份的开始日期和实际访问日期AGE的结束日期之间的差异,以给出一个可以公平地视为一个月的间隔,然后向其添加 1,如您所提到的。这给出了预期的结果。

first_access在 CTE 中单独计算,因为它是每个 id 的单个值,而不是每个 id、月份、年份。

with m AS
(
select id, min(date_accessed)
                    as first_access from t
group by id
)
select t.id, Extract(MONTH from "date_accessed") as month, 
             Extract(year from  "date_accessed") as year,
            EXTRACT ( month from 
                      MIN( AGE( date_trunc('month', date_accessed) 
                                + interval '1 month - 1 day',  --last day of month
                             date_trunc('month', first_access) --first day of month
                         ))
                    ) + 1 as length_in_month
from t join m on t.id = m.id 
group by t.id,month,year 
order by 1,3,2;
Run Code Online (Sandbox Code Playgroud)

演示版