带有 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)。
我需要使用 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)。