sql - 如何在保留一张表的准确信息的同时连接表?

标签 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     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 时间 1 的时间段,我希望 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

但它不能正确处理没有匹配的情况。我该怎么做?

我在 Redshift 上这样做。

最佳答案

因为您只需要 t2 中的第一个匹配行,您可以使用带有 LIMIT 子句的 LATERAL 子查询:

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

关于sql - 如何在保留一张表的准确信息的同时连接表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39644037/

相关文章:

mysql - 使用 Inner Join 确定表中特定记录和相关事件之间的间隔

mysql - SQL 使用另一个数据库中的值更新 1 个数据库中表中的值

mysql - SQL:连接表也显示空值

sql - 如何计算 SQL Server 中的第 90 个百分位数

C++ 数据库持久化

PHP 和 PostgreSQL 交易?

mysql更新行到以前的枚举值

ruby-on-rails - 使用 beginning_of_month 时 Rails 5 中的时区

sql - 获取数组元素空格分隔而不是逗号分隔

javascript - column 是没有时区的 timestamp 类型,但 expression 是 integer 类型