[英]Postgres LEFT JOIN with WHERE condition
I need to left join two tables with a where condition:我需要左加入两个带有 where 条件的表:
Table time_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
表
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
I need to get all those records which are present under given date range.我需要获取在给定日期范围内存在的所有记录。 In the above example, I need those records that lie under range for
rid = 2
only.在上面的示例中,我只需要那些在
rid = 2
范围内的记录。 Hence the output for the above query needs to be:因此,上述查询的输出需要是:
1 record1 2017-10-01 00:00:00
3 record3 2017-10-01 00:00:00
left join two tables with a where condition
left join 两个带有 where 条件的表
It's typically wrong to use a LEFT [OUTER] JOIN
and then filter with a WHERE
condition, thereby voiding the special feature of a LEFT JOIN
to include all rows from the left table unconditionally .使用
LEFT [OUTER] JOIN
然后使用WHERE
条件进行过滤通常是错误的,从而使LEFT JOIN
的特殊功能无效,即无条件地包含左表中的所有行。 Detailed explanation:详细解释:
Put conditions supposed to filter all rows into the WHERE
clause ( rid = 2
), but make conditions to left-join rows from record_table
out to be actual join conditions:将应该过滤所有行的条件放入
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 , it makes sense to include columns from time_table
in the result, but that's my optional addition. 正如所评论的,在结果中包含来自
time_table
的列是有意义的,但这是我的可选添加。
You also need to be clear about lower and upper bounds .您还需要清楚下限和上限。 The general convention is to include the lower and exclude the upper bound in time (
timestamp
) ranges.一般约定是在时间(
timestamp
)范围内包括下限并排除上限。 Hence my use of >=
and <
above.因此我在上面使用
>=
和<
。
Related:有关的:
Performance should be no problem at all with the right indexes.使用正确的索引,性能应该完全没有问题。 You need an index (or PK) on
time_table(rid)
and another on record_table(date)
.您需要
time_table(rid)
上的索引(或 PK)和 record_table( record_table(date)
上的另一个索引。
I'm not exactly sure if this is what you want, but if you are saying you want the dates where the record_table date is between the dates in the time_table, then this would do the job:我不确定这是否是你想要的,但如果你说你想要 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
That said, this will be horribly inefficient for large datasets.也就是说,对于大型数据集,这将是非常低效的。 If your data is relatively small (< 10k records in each table, post-filters), then it probably won't matter much, but if you would need to scale this concept, it would warrant knowing more about your data -- for example, do the dates, always round to the first of each month?
如果您的数据相对较小(每个表中 < 10k 条记录,后过滤器),那么它可能并不重要,但如果您需要扩展这个概念,则需要更多地了解您的数据 - 例如,做日期,总是四舍五入到每个月的第一天?
Again, from your example, I wasn't sure if this is what you meant by "get all those records which are present under given date range."同样,从您的示例中,我不确定这是否是您所说的“获取在给定日期范围内存在的所有记录”的意思。
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.