带有 WHERE 条件的 Postgres LEFT JOIN

Postgres LEFT JOIN with WHERE condition

我需要使用 where 条件左连接两个表:

Table time_table

id     rid        start_date                end_date
1       2     2017-07-01 00:00:00     2018-11-01 00:00:00
2       5     2017-01-01 00:00:00     2017-06-01 00:00:00
3       2     2018-07-01 00:00:00     2020-11-01 00:00:00

Table record_table

id      name                 date
1      record1       2017-10-01 00:00:00
2      record2       2017-02-01 00:00:00
3      record3       2017-10-01 00:00:00

我需要获取在给定日期范围内出现的所有记录。在上面的示例中,我只需要那些位于 rid = 2 范围内的记录。因此,上述查询的输出需要为:

1      record1       2017-10-01 00:00:00    
3      record3       2017-10-01 00:00:00
SELECT time_tbl.name,record_tbl.date 
FROM dbo.time_table AS time_tbl
     INNER JOIN record_table AS record_tbl
           ON time_tbl.id=record_tbl.id
WHERE(time_tbl.rid=2)       

我不确定这是否是您想要的,但是如果您说您想要 record_table 日期介于 time_table 中的日期之间的日期,那么这将完成任务:

select
  rt.id, rt.name, rt.date
from
  time_table tt
  join record_table rt on
    rt.date between tt.start_date and tt.end_date
where
  tt.rid = 2

也就是说,这对于大型数据集来说效率非常低。如果您的数据相对较小(每个 table、post-过滤器中有 < 10k 条记录),那么它可能无关紧要,但如果您需要扩展这个概念,则有必要知道有关您的数据的更多信息 -- 例如,日期是否始终四舍五入到每个月的第一天?

同样,根据您的示例,我不确定这是否是您所说的 "get all those records which are present under given date range."

left join two tables with a where condition

通常 错误 使用 LEFT [OUTER] JOIN 然后使用 WHERE 条件过滤,从而使 LEFT JOIN 的特殊功能失效无条件地 table 包括从左边开始的所有行 。详细解释:

  • Explain JOIN vs. LEFT JOIN and WHERE condition performance suggestion in more detail

将应该过滤所有行的条件放入 WHERE 子句 (rid = 2),但将条件从 record_table 左连接行设为实际连接条件:

SELECT t.start_date, t.end_date  -- adding those
     , r.id, r.name, r.date 
FROM   time_table t
LEFT   JOIN record_table r ON r.date >= t.start_date
                          AND r.date <  t.end_date
WHERE  t.rid = 2;

,在结果中包含来自 time_table 的列是有意义的,但这是我的可选添加。

你还需要清楚下限和上限。一般惯例是 include 下限和 exclude 时间上限 (timestamp) 范围。因此我在上面使用 >=<

相关:

  • Selecting an average of records grouped by 5 minute periods

使用正确的索引,性能应该完全没有问题。 您需要 time_table(rid) 上的索引(或 PK)和 record_table(date) 上的另一个索引(或 PK)。