关于java:如何分组使用月份从日期存储为毫秒Postgres

How to Group By using Month from date stored as millisecond Postgres

我有一个包含net_amount字段和last_updated_time字段的事务表,其中last_updated_time存储为毫秒。 我需要使用月,年或日期来获得总金额组。 我怎么能在PostgreSQL中做到这一点?

我的表如下所示:

1
2
3
4
5
6
7
8
9
+------------+-------------------+
| net_amount | last_updated_time |
+------------+-------------------+
| 100        | 1470286872831     |
+------------+-------------------+
| 200        | 1471594713801     |
+------------+-------------------+
| 300        | 1471594651335     |
+------------+-------------------+

期待结果如下:

1
2
3
4
5
6
7
8
9
+----------+---------------+
| month    | sum_of_amount |
+----------+---------------+
| january  | 1000          |
+----------+---------------+
| february | 2000          |
+----------+---------------+
| ---      | ----          |
+----------+---------------+


你可以这样做:

1
2
3
SELECT sum(amount), date_trunc('month', to_timestamp(last_updated_time/1000))
FROM transaction
GROUP BY date_trunc('month', to_timestamp(last_updated_time/1000));

我刚刚在我的项目数据库中检查了它,它对我有用。

编辑:我将last_update_time转换为时间戳,如@a_horse_with_no_name所指出的。


如果我正确理解您的问题,您可能会尝试执行以下操作(Java 8)

1
2
3
4
5
6
7
8
9
10
11
12
     long day1MSec, day2MSec ;

     LocalDate localDate1 = LocalDate.of( 2011 , Month.JULY , 3 );    
     LocalDate localDate2 = LocalDate.of( 2011 , Month.JULY , 25 );    

     final long msPerDay = 24 * 60 * 60 * 1000;//milisec per day

     day1MSec = localDate1.toEpochDay() * msPerDay;
     day2MSec = localDate2.toEpochDay() * msPerDay;

     //now your sql would look something like
     String sql ="select sum(amount)from transaction group by last_updated having last_updated between"+day1MSec +" and"+day2MSec;

因此,您需要在Java代码中执行的操作是将日期转换为毫秒。如果您想使用数月或数年,只需调整您的日期以匹配一个月或一年的开始日期。

1
LocalDate localDate1 = LocalDate.of( 2011 , Month.JANUARY , 1 );

更新:对于低于8的java版本,您可以使用

1
2
     Date date =     new SimpleDateFormat("yyyy-MM-dd", Locale.ITALY).parse("2015-06-25");
     long mSec = date.getTime(); //this returns miliseconds

奇怪的是,这两个版本在产生的结果上有所不同,所以我想知道第一个版本中是否存在错误(因为第二个版本似乎给出了正确的结果)


您可以编写一个查询,为您提供所有准备好的聚合:

1
2
3
4
5
6
7
8
9
10
11
12
13
create table Transaction
(
    amount DECIMAL(9,2),
    last_updated_time BIGINT
);

insert into Transaction values (10, 1472680800000); -- 2016-09-01
insert into Transaction values (20, 1473458400000); -- 2016-09-10
insert into Transaction values (30, 1474408800000); -- 2016-09-21
insert into Transaction values (5,  1475272800000); -- 2016-10-01
insert into Transaction values (2,  1475272800000); -- 2016-10-01
insert into Transaction values (7,  1475272800000); -- 2016-10-02
insert into Transaction values (15, 1478818800000); -- 2016-11-11

使用EXTRACT与to_timestamp组合以提取您想要的内容(MONTHYEAR)然后group by

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
select
    sum(amount),
    EXTRACT(MONTH FROM to_timestamp(last_updated_time/1000)) as month
from Transaction
group by month order by month asc;

  sum  | month
-------+-------
 60.00 |     9
 14.00 |    10
 15.00 |    11


select
    sum(amount),
    EXTRACT(YEAR FROM to_timestamp(last_updated_time/1000)) as year
from Transaction
group by year order by year asc;

  sum  | year
-------+--------
 89.00 |   2016

最后,为了解决我的评论,您可以select select中的年份和月份,然后group by两者(请参阅此处)。