[英]Postgres LEFT JOIN with WHERE condition
我需要左加入两个带有 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
left join 两个带有 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;
正如所评论的,在结果中包含来自time_table
的列是有意义的,但这是我的可选添加。
您还需要清楚下限和上限。 一般约定是在时间( timestamp
)范围内包括下限并排除上限。 因此我在上面使用>=
和<
。
有关的:
使用正确的索引,性能应该完全没有问题。 您需要time_table(rid)
上的索引(或 PK)和 record_table( record_table(date)
上的另一个索引。
我不确定这是否是你想要的,但如果你说你想要 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 条记录,后过滤器),那么它可能并不重要,但如果您需要扩展这个概念,则需要更多地了解您的数据 - 例如,做日期,总是四舍五入到每个月的第一天?
同样,从您的示例中,我不确定这是否是您所说的“获取在给定日期范围内存在的所有记录”的意思。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.