在分组时始终获取用户的最新记录:SQL

时间:2018-02-12 19:40:10

标签: sql postgresql group-by

我有一个看起来像这样的postgres表:

user_id date          val
1       2015-01-01    1
2       2015-01-01    2
1       2015-01-30    7
3       2015-02-01    1
3       2015-02-05    7
3       2015-02-12    3
4       2015-02-10    1
4       2015-02-11    2

我希望能够按月分组获得val的总和,使其仅计算用户最新值的总和。

预期产出:

date         sum
2015-01-01   9
2015-02-01   5

我希望有一些灵活的东西允许使用相同的代码以不同的方式聚合。所以如果我决定按user_id分组

user_id   sum
1         7
3         3
4         2

我可以想到基于max等的一些复杂的SQL加入。但我想知道是否有更优雅的东西?

2 个答案:

答案 0 :(得分:0)

每月总和最多:

-- sum the inner max values using only the date to group by
select d, sum(maxV) as sumMaxV
from
(
    SELECT DISTINCT  -- needed to trim down results from partition
    date_trunc('month',dated) as d,
    first_value(val) OVER ( -- only the first result is taken for each partition, they are 
                            -- identical due to ordering, hence we need distinct them
        PARTITION BY date_trunc('month',dated), user_id     
        ORDER BY val DESC) as maxV   
    FROM T
) tmp
group by d

结果:

d                      sumMaxV
2015-01-01T00:00:00Z      9
2015-02-01T00:00:00Z      9

每月最后一次总结:

-- sum the inner lastV values using only the date to group by
select d, sum(lastV) as sumLastV
from
(
    SELECT DISTINCT   
    date_trunc('month',dated) as d,
    first_value(val) OVER ( 
        PARTITION BY date_trunc('month',dated), user_id     
        ORDER BY dated DESC) as lastV   
    FROM T
) tmp
group by d

输出:

d                      sumlastv
2015-01-01T00:00:00Z      9
2015-02-01T00:00:00Z      5

数据:

CREATE TABLE T  ("user_id" int, "dated" timestamp, "val" int);    
INSERT INTO T   ("user_id", "dated", "val")
VALUES          (1, '2015-01-01 00:00:00', 1),
                (2, '2015-01-01 00:00:00', 2),
                (1, '2015-01-30 00:00:00', 7),
                (3, '2015-02-01 00:00:00', 1),
                (3, '2015-02-05 00:00:00', 7),
                (3, '2015-02-12 00:00:00', 3),
                (4, '2015-02-10 00:00:00', 1),
                (4, '2015-02-11 00:00:00', 2);

答案 1 :(得分:0)

以下版本允许您按用户或日期分组(灵感来自@Patrick Artner的解决方案)

@Override
public View getView(final int position, View convertView, ViewGroup parent){
      TextView textView = (TextView)view.findViewById(R.id.gridview_textview);
      textView.setText(values[position]);
};