46

我正在使用PostgreSQL 8.3。我有一张这样的桌子:

id        regist_time        result
-----------------------------------
1     2012-07-09 15:00:08      3
2     2012-07-25 22:24:22      7
4     2012-07-07 22:24:22      8

regist_time的数据类型是timestamp

我需要找到一个星期的时间间隔(开始到结束)和总和(结果)作为 num。

我想得到结果:

      week                    num    
---------------------------------
7/1/2012-7/7/2012              10
7/8/2012-7/14/2012              5
7/15/2012-7/21/2012             3
7/22/2012-7/28/2012            11

我可以得到今年的周数:

SELECT id,regis_time, EXTRACT(WEEK FROM regis_time) AS regweek
FROM tba

关键部分是

EXTRACT(WEEK FROM regis_time) 

提取函数只能获取今年的周数,如何获取一周内的开始时间到结束时间?

4

5 回答 5

101

您可以使用date_trunc('week', ...).

例如:

SELECT date_trunc('week', '2012-07-25 22:24:22'::timestamp);
-> 2012-07-23 00:00:00

然后,如果您对开始时间不感兴趣,可以将其转换为日期。

要获得结束日期:

SELECT    date_trunc('week', '2012-07-25 22:24:22'::timestamp)::date
   || ' '
   || (date_trunc('week', '2012-07-25 22:24:22'::timestamp)+ '6 days'::interval)::date;

-> 2012-07-23 2012-07-29

(我在这里使用了默认格式,您当然可以将其调整为使用 MM/DD/YYYY。)

请注意,如果您想对时间戳进行比较,而不是使用(date_trunc('week', ...) + '6 days'::interval,您可能希望添加一整周并在一周结束时使用严格比较。

这将排除y一周最后一天的时间戳(因为截止时间是当天的午夜)。

    date_trunc('week', x)::date <= y::timestamp
AND y::timestamp <= (date_trunc('week', x) + '6 days'::interval)::date

这将包括他们:

    date_trunc('week', x)::date <= y::timestamp
AND y::timestamp < (date_trunc('week', x) + '1 week'::interval)

(在极少数情况下,您不能直接使用date_truncon y。)


如果您的一周从星期日开始,则替换date_trunc('week', x)::datedate_trunc('week', x + '1 day'::interval)::date - '1 day'::interval应该可以。

于 2012-08-01T15:02:34.607 回答
18
select date_trunc('week', regist_time)::date || ' - ' ||
       (date_trunc('week', regist_time) + '6 days') ::date as Week,
       sum(result) Total
from YourTable
group by date_trunc('week', regist_time)
order by date_trunc('week', regist_time)

请参阅 SQLFiddle 上的概念证明:http ://sqlfiddle.com/#!1/9e821/1

于 2012-08-01T15:09:35.423 回答
5

这可以帮助查询获取当前一周的所有天数。

select cast(date_trunc('week', current_date) as date) + i
from generate_series(0,6) i

2015-08-17
2015-08-18
2015-08-19
2015-08-20
2015-08-21

获取星期的开始和结束日期(星期一为 0,星期五为 4):

select cast(date_trunc('week', current_date) as date) + 0 || '-->' ||  cast(date_trunc('week', current_date) as date) + 4;

2015-08-17-->2015-08-21

于 2015-08-18T10:52:25.723 回答
3

这是

select to_date('2015-07', 'IYYY-IW');

在 postgres 中使用它

它会回来

2015-02-09
于 2015-02-11T21:10:28.717 回答
0

如果您想获得一周的开始和结束日期,一周的开始日是一周中的任何一天(星期一,星期二,...)。你可以这样使用:

day_of_week_index映射:

{
    'monday': 1,
    'tuesday': 2,
    'wednesday': 3,
    'thursday': 4,
    'friday': 5,
    'saturday': 6,
    'sunday': 7
}

查询模板:

SELECT 
concat(
    CASE
        WHEN extract(ISODOW FROM datetime_column) < day_of_week_index THEN cast(date_trunc('week', datetime_column) AS date) - 8 + day_of_week_index
        ELSE cast(date_trunc('week', datetime_column) AS date) - 1 + day_of_week_index
    END, ' - ', 
    CASE
        WHEN extract(ISODOW FROM datetime_column) < day_of_week_index THEN cast(date_trunc('week', datetime_column) AS date) - 8 + day_of_week_index + 6
        ELSE cast(date_trunc('week', datetime_column) AS date) - 1 + day_of_week_index + 6
    END) 
FROM table_name;

例子:

获取星期开始和结束日期,星期开始日是星期二

SELECT 
concat(
    CASE
        WHEN extract(ISODOW FROM TIMESTAMP '2021-12-01 03:00:00') < 2 THEN cast(date_trunc('week', TIMESTAMP '2021-12-01 03:00:00') AS date) - 8 + 2
        ELSE cast(date_trunc('week', TIMESTAMP '2021-12-01 03:00:00') AS date) - 1 + 2
    END, ' - ', 
    CASE
        WHEN extract(ISODOW FROM TIMESTAMP '2021-12-01 03:00:00') < 2 THEN cast(date_trunc('week', TIMESTAMP '2021-12-01 03:00:00') AS date) - 8 + 2 + 6
        ELSE cast(date_trunc('week', TIMESTAMP '2021-12-01 03:00:00') AS date) - 1 + 2 + 6
    END);

=> 结果:

2021-11-30 - 2021-12-06

注意:您可以更改day_of_week_index以下上述映射以确定一周的开始日期(星期一,星期二,...,星期日)

于 2021-12-15T10:10:20.293 回答