Sql 如何连接表,同时保留一个表上的确切信息?
我想通过将一个表中的时间与第二个表中的时段(开始和结束时间)匹配来连接两个表,我需要这样做,以便操作保留一个表上的确切信息。更具体地说,我有这些表格 表t1:Sql 如何连接表,同时保留一个表上的确切信息?,sql,postgresql,Sql,Postgresql,我想通过将一个表中的时间与第二个表中的时段(开始和结束时间)匹配来连接两个表,我需要这样做,以便操作保留一个表上的确切信息。更具体地说,我有这些表格 表t1: cid time1 A 2016-01-05 11:00:00 A 2016-01-15 11:00:00 A 2016-01-25 11:00:00 B 2016-01-09 11:00:00 表t2: cid period_start period_end A 201
cid time1
A 2016-01-05 11:00:00
A 2016-01-15 11:00:00
A 2016-01-25 11:00:00
B 2016-01-09 11:00:00
表t2:
cid period_start period_end
A 2016-01-01 00:00:00 2016-01-10 00:00:00
A 2016-01-10 00:00:00 2016-01-16 00:00:00
A 2016-01-12 00:00:00 2016-01-20 00:00:00
我希望输出为:
cid time1 period_start period_end
A 2016-01-05 11:00:00 2016-01-01 00:00:00 2016-01-10 00:00:00
A 2016-01-15 11:00:00 2016-01-10 00:00:00 2016-01-16 00:00:00
A 2016-01-25 11:00:00 NULL NULL
B 2016-01-09 11:00:00 NULL NULL
一些附加信息/条件:
- 我希望t1上的信息准确地保留在输出中(例如,t1上没有行连接到t2上的多行,t1中没有行在输出中丢失)。换句话说,我只想把t2中的信息作为列添加到t1中
- 如果t2中没有包含t1上的time1的时段,我希望period_start和period_end为NULL
- t2上可能根本没有匹配的cid
- 如果t2上有多个匹配项,我只想要第一个
SELECT t1.*, t2.period_start, t2.period_end
FROM t1
LEFT JOIN t2 ON t1.cid = t2.cid
WHERE t2.period_start >= t1.time1
AND t2.period_end <= t1.time1
选择t1.*,t2.period\u start,t2.period\u end
从t1开始
t1上的左连接t2.cid=t2.cid
其中t2.period\u start>=t1.time1
和t2.period_end将t2上的过滤器从where子句移动到join
FROM t1 LEFT JOIN t2 ep ON t1.cid = t2.cid
and t2.period_start >= t1.time1
AND t2.period_end <= t1.time1
从t1左侧连接t1.cid上的t2 ep=t2.cid
和t2.period\u start>=t1.time1
和t2.period_end您可以使用以下查询:
SELECT cid, time1, period_start, period_end
FROM (
SELECT t1.cid, t1.time1, t2.period_start, t2.period_end,
ROW_NUMBER() OVER (PARTITION BY t1.cid, t1.time1
ORDER BY t2.period_start) AS rn
FROM t1
LEFT JOIN t2 ON t1.cid = t2.cid AND
t1.time1 BETWEEN t2.period_start AND t2.period_end) AS t
WHERE t.rn = 1
ROW\u NUMBER
用于在多个匹配项的情况下从t1
表中选择一条记录 因为您只需要t2
中的第一个匹配行,所以可以使用带有限制
子句的横向
子查询:
SELECT t1.cid, t1.time1, t2.period_start, t2.period_end
FROM t1 LEFT JOIN LATERAL
(SELECT *
FROM t2
WHERE cid=t1.cid AND t1.time1 BETWEEN period_start AND period_end
ORDER BY t2.period_start
LIMIT 1
) t2 ON true
这对我不起作用,因为t1中的1月15日连接到t2中的两行。我只想要第一个。