使用Postgresql的前一周的第一天和最后一天

 2021-04-26 

First and Last day of the previous week with Postgresql

我正在尝试使用postgresql查询上周的第一天和最后一天的方法。

我已经找到了针对mysql,sql server和其他服务器的答案,但找不到针对PSQL的答案。

我一直在尝试使用current_date和时间间隔1 week- integer '7'(BETWEEN current_date - INTERVAL '1 weeks' and current_date),但是它给我的日期是从当天退后1周,而不是上周的第一天或最后一天。

我正在寻找动态的东西:上周的第一天可能是星期二,而周四的最后一天并不总是星期一,星期五取决于上周的存储内容。

我需要能够检索上周第一天和最后一天的结果,所以我相信这将是2个查询。

edit:我的主要问题是,围绕同一问题的大多数答案都使用current_date / now()并减去固定的天数来检索上周的第一天。但是查询应该是动态的,不会在每周的同一天进行-因此根据执行查询的日期,天数的减法会有所不同-而且我存储的上周的第一天不是t总是星期一,而最后一天也不总是星期五。有时我一周只有3天的数据,所以第一天是星期二,最后一天是星期四,我不想在星期一返回NULL,在星期五返回Null

编辑2:

虚拟数据如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
id |  DATE        
 1    monday(w1)      
 2    tuesday(w1)
 3    wednesday(w1)
 4    thursday(w1)
 5    friday(w1)
 6    tuesday(w2)
 7    wednesday(w2)
 8    friday(w2)
 9    monday(w3)
10    tuesday(w3)
    --query ran here--

很明显,我的日期存储为实际的日期格式(2019-10-24),但是在查询的日期(催眠星期三),我希望上周的第一项为id 6,最后一项为是ID 8


从我正在阅读的内容中,您正在寻找一周中的第一天和最后一天,因此:

1
2
3
4
WITH
  first_stored AS (SELECT MIN(stored_date) AS FIRST FROM stored WHERE stored_date > DATE_TRUNC('WEEK', NOW()) - INTERVAL '8 DAY'),
  last_stored AS (SELECT MAX(stored_date) AS LAST FROM stored WHERE stored_date < DATE_TRUNC('WEEK', NOW()) - INTERVAL '1 DAY')
SELECT first_stored.first, last_stored.last FROM first_stored, last_stored;

这将产生:

1
2
3
4
   FIRST    |    LAST    
------------+------------
 2019-10-15 | 2019-10-18  -- a Tuesday and a Thursday
(1 ROW)

更新:

假设"今天"是2019-10-26(对问题的最新编辑的时间戳),则此版本适合您共享的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
postgres=# CREATE TABLE my_table (id INT, stored_date DATE);
CREATE TABLE
postgres=# INSERT INTO my_table VALUES (1,'2019-10-07'),(2,'2019-10-08'),(3,'2019-10-09'),(4,'2019-10-10'),(5,'2019-10-11'),(6,'2019-10-15'),(7,'2019-10-16'),(8,'2019-10-18'),(9,'2019-10-21'),(10,'2019-10-22');
INSERT 0 10
postgres=# WITH
  first_stored AS (SELECT MIN(stored_date) AS FIRST FROM my_table WHERE stored_date > DATE_TRUNC('WEEK', '2019-10-26'::DATE) - INTERVAL '8 DAY'),
  last_stored AS (SELECT MAX(stored_date) AS LAST FROM my_table WHERE stored_date < DATE_TRUNC('WEEK', '2019-10-26'::DATE) - INTERVAL '1 DAY')
SELECT id, stored_date FROM my_table mt, first_stored fs, last_stored ls WHERE mt.stored_date IN (fs.first,ls.last) ORDER BY stored_date;
 id | stored_date
----+-------------
  6 | 2019-10-15
  8 | 2019-10-18
(2 ROWS)

披露:我为EnterpriseDB(EDB)工作


您可能想要这样的东西(请参阅小提琴):

1
2
SELECT DATE_TRUNC('WEEK', NOW()) - INTERVAL '8 DAY' AS first_day_of_last_week,
       DATE_TRUNC('WEEK', NOW()) - INTERVAL '1 DAY' AS  last_day_of_last_week;

结果:

1
2
first_day_of_last_week  last_day_of_last_week
2019-10-13 00:00:00+01  2019-10-20 00:00:00+01