在Postgres的两个日期之间的几周

时间:2014-06-06 05:31:33

标签: sql postgresql

我想计算一个客户成为客户的周数。目标是将此与客户进行购买的不同周数进行比较,以确定客户购买的周数百分比。

使用时间戳customer.created_at,找到客户成为客户的周数的最佳方法是什么?换句话说,当前一周与客户注册的那一周之间的差异。

从星期一开始的日历周与客户购买的不同日历周进行一对一。

9 个答案:

答案 0 :(得分:4)

SELECT (EXTRACT(days FROM (now() - customer.created_at)) / 7)::int;

首先找出当前时间与客户的created_at时间戳之间的差异。 然后你告诉Postgres给你几天的差异,然后你可以将它除以7并将其四舍五入为整数。请注意,如果您不想要整数,则可以进行适当的转换。

答案 1 :(得分:3)

AFAIK在所有情况下均应如此

-您的日历周从星期一开始
-两个日期均至少从1970年5月1日(星期一)开始

Postgres:

SELECT
(
extract(epoch from date_trunc('week',now()::date))
-
extract(epoch from date_trunc('week','2019-12-20'::date))
)
/604800

(其中604800是一周中的秒数)

答案 2 :(得分:1)

这是我使用的代码。的工作原理。

SELECT
  (
    (
      (
        CURRENT_DATE::DATE - (EXTRACT('dow' FROM CURRENT_DATE::DATE) * INTERVAL '1 day')
      )::DATE -
      (
        customers.created_at::DATE - (EXTRACT('dow' FROM customers.created_at::DATE) * INTERVAL '1 day')
      )::DATE
    ) / 7
  ) + 1

答案 3 :(得分:0)

试试这个

select (CURRENT_DATE - customer.created_at)/7

答案 4 :(得分:0)

@zach的答案(也许)是有效的,但是很难遵循。

我发现了这两个抽象等效逻辑的过程:

CREATE OR REPLACE FUNCTION first_of_week(date) returns date AS $$
  SELECT ($1::date-(extract('dow' FROM $1::date)*interval '1 day'))::date;
$$ LANGUAGE SQL STABLE STRICT;

CREATE OR REPLACE FUNCTION weeks_in_range(date,date) returns int AS $$
  SELECT ((first_of_week($2)-first_of_week($1))/7)+1
$$ LANGUAGE SQL STABLE STRICT;

来源:

https://gist.github.com/tkellen/2003309#file-gistfile1-sql-L17-L23

示例:

SELECT weeks_in_range('1900-01-01',CURRENT_DATE);
 weeks_in_range 
----------------
           5854
(1 row)

请注意,以上示例假定星期日是一周的开始。另外,如果您希望星期一作为一周的开始,则使用date_trunc,例如

CREATE OR REPLACE FUNCTION weeks_in_range(date,date) returns int AS $$
  SELECT (((EXTRACT(DAY FROM (date_trunc('week', $2::date) - date_trunc('week', $1::date))))/7)+1)::int
$$ LANGUAGE SQL STABLE STRICT;
在这种情况下,

first_of_week是不必要的。

答案 5 :(得分:0)

var providerStatus = providerBookingResponse.Message;

BookingStatus status = new BookingStatus();

switch (providerStatus.ToLower())
{
    case "success":
        status = BookingStatus.Confirmed;
        break;
    case "failed":
        status = BookingStatus.Failed;
        break;
    case "":
        status = BookingStatus.Failed;
        break;
}
return status;

这应该可以解决问题。

答案 6 :(得分:0)

这在大多数情况下都适用于Postgres(每周从星期一开始,一年有52周)

示例到2019年底:

select 
extract( isoyear from '2020-01-04'::date)*52 + extract( week from '2020-01-04'::date)
-
extract( isoyear from '2019-12-29'::date)*52 - extract( week from '2019-12-29'::date) 

答案 7 :(得分:0)

反驳@maleckicoa。以下内容说明了为什么不能使用一年中52周的常量作为跨12月到1月时间范围的日期之间的差异。
代替了对2019年12月至2020年1月的硬编码(效果很好),它生成了2019年至2030年的年度日期为12月29日至12月4日。在大多数maleckicoa的算法中,但...

with recursive annual_dates(dec_dt, jan_dt) as 
     ( select make_date(2019,12,29), make_date(2020,01,04)
       union all 
       select (dec_dt+interval '1 year')::date, (jan_dt+interval '1 year')::date
         from annual_dates 
        where extract(isoyear from dec_dt)::integer < 2030        
     )  --select * from annual_dates; 

select dec_dt, jan_dt, 
       extract( isoyear from jan_dt)*52 + extract( week from jan_dt)
       -
       extract( isoyear from dec_dt)*52 - extract( week from dec_dt) "Weeks Between" 
  from annual_dates;       


with recursive annual_dates(dec_dt, jan_dt) as 
     ( select make_date(2019,12,29), make_date(2020,01,04)
       union all 
       select (dec_dt+interval '1 year')::date, (jan_dt+interval '1 year')::date
         from annual_dates 
        where extract(isoyear from dec_dt)::integer < 2030        
     )  --select * from annual_dates; 
select 'Week for ' || dec_dt || ' is ' || extract( week from dec_dt) || ' And '
       'Week for ' || jan_dt || ' is ' || extract( week from jan_dt) || ' Giving Difference of '
        || extract( isoyear from jan_dt)*52 + extract( week from jan_dt)
           -
          extract( isoyear from dec_dt)*52 - extract( week from dec_dt) || ' Weeks Between' 
  from annual_dates;

答案 8 :(得分:-1)

我认为你可以通过这个来获得日历周

select to_char(i::date, 'IYYYIW') AS mdate from generate_series('2017-01-01', current_date, '1 week'::interval) i;

并计算

select count(to_char(i::date, 'IYYYIW')) from generate_series('2017-01-01', current_date, '1 week'::interval) i;

您可以将日期替换为客户日期