【问题标题】:PostgreSQL - Filtering join using date ranges by groupPostgreSQL - 按组使用日期范围过滤连接
【发布时间】:2021-09-17 01:42:29
【问题描述】:

我有两张桌子:

表 1:包含事件发生列表的表,每个唯一事件具有唯一 ID (event_id)、事件日期 (date_event) 和每个人的性别 (@ 987654323@):

person| event_id| date_event | gender|
----- |---------|------------|-------|
a     |  86i    | 2012-01-25 |   m   |
a     |  87i    | 2012-05-30 |   m   |
a     |  88i    | 2012-09-20 |   m   |
a     |  89i    | 2012-12-20 |   m   |
b     |  15i    | 2015-04-06 |   f   |
b     |  16i    | 2016-07-06 |   f   |
b     |  17i    | 2016-04-30 |   f   |
b     |  18i    | 2016-11-28 |   f   |
----- |---------|------------|-------|

表 2:列出开始日期 (date_start) 和结束日期 (date_end) 的日期表,表示每个人参加计划的时间范围:

person| date_start | date_end   |
----- |------------|------------|
a     | 2012-02-05 | 2012-03-30 |
a     | 2012-06-26 | 2012-08-28 |
a     | 2012-09-15 | 2012-12-31 |
b     | 2015-01-24 | 2015-03-30 |
b     | 2016-07-01 | 2016-10-01 |
b     | 2016-11-25 | 2016-12-30 |
----- |------------|------------|

我希望能够过滤表 1,使其仅包含此人注册某个计划时发生的事件记录,该记录将指定为介于 date_startdate_end 之间的 date_event。我想要的结果表如下所示:

期望的结果

person| event_id| date_event | gender|
----- |---------|------------|-------|
a     |  88i    | 2012-09-20 |   m   |
a     |  89i    | 2012-12-20 |   m   |
b     |  16i    | 2016-07-06 |   f   |
b     |  18i    | 2016-11-28 |   f   |
----- |---------|------------|-------|

我尝试了以下几种变体均无济于事:

CREATE TABLE temptable AS
SELECT * 
FROM table1 t1
LEFT JOIN table2 t2 
USING(person);

CREATE TABLE desiredresult AS
SELECT * 
FROM temptable 
WHERE date_event BETWEEN date_start AND date_end
GROUP BY person;

我承认我绝对是一个 SQL 新手,并且习惯于使用 R,我可以使用下面的代码来实现我想要的结果。但是,我使用的数据集非常庞大,所以我需要弄清楚如何在 SQL 服务器上执行这些操作。

library(dplyr)
library(lubridate)

desiredresult <- table1 %>%
    left_join(table2) %>%
    group_by(person) %>%
    mutate(keep_record = date_event %within% interval(start_date, end_date)) %>%
    filter(keep_record == TRUE)

提前致谢。

【问题讨论】:

    标签: postgresql date join filter


    【解决方案1】:

    没有理由创建临时表,并花费处理时间这样做。只需直接从 JOIN 中选择。 (见Demd

    select t1.* 
      from table1 t1
      join table2 t2 
        on (     t1.person = t2.person
             and t1.date_event between t2.date_start and t2.date_end 
           ) ;   
    

    【讨论】:

      猜你喜欢
      • 2013-03-26
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      相关资源
      最近更新 更多