Postgres Left加入条件

时间:2016-11-07 12:31:12

标签: mysql sql postgresql left-join date-range

我需要将两个表连接到where条件:

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
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

3 个答案:

答案 0 :(得分:8)

  

左边连接两个带有where条件的表

这里有一个 陷阱 等着你。使用LEFT [OUTER] JOIN时,通常错误WHERE条件进行过滤,从而排除LEFT JOIN的特殊功能以包含左表中的所有行无条件。详细解释:

因此,将条件放入应该过滤所有行(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;

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

您还需要非常清楚上限和下限。一般约定是包括 lower和 exclude 时间上限(timestamp)范围。因此我使用上面的>=<

相关:

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

答案 1 :(得分:0)

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)       

答案 2 :(得分:0)

我不确定这是否是你想要的,但如果你说你想要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

也就是说,对于大型数据集来说,这将是非常低效的。如果您的数据相对较小(每个表中的记录<10k,后过滤器),那么它可能会非常重要,但如果您需要扩展此概念,则需要了解有关您数据的更多信息 - - 例如,做日期,总是在每个月的第一天?

同样,从你的例子来看,我不确定这是否是你所指的那样&#34;获取在给定日期范围内出现的所有记录。&#34;