SQL:在第一个匹配行条件下连接 2 个表

标签 sql postgresql

我有两个正确的表

用户旅程

id  timestamp     bus 
1       00:10      12
1       16:10      12
2       14:00      23

公交车

id   timestamp    price
12   00:00        1.3
12   00:10        1.5
12   00:20        1.7
12   18:00        2.0
13   00:00        3.0

我的目标是找出每个用户今天在旅行上花费了多少。

在我们的案例中,用户在 00:10 乘坐 12 路公交车并支付 1.5,在 16:10 乘坐另一辆公交车,价格上涨至 1.7。这个人今天总共支付了 3.2。我们始终采用最新的更新价格。

我使用大量子查询完成了这项工作,但看起来效率很低。有人有巧妙的解决方案吗?


重现样本数据:


请参阅http://sqlfiddle.com/#!17/10ad6/2

或构建模式:

drop table if exists journeys;
create table journeys(
id numeric,
timestamp timestamp without time zone,
bus numeric
);

truncate table journeys;
insert into journeys
values
(1, '2018-08-22 00:10:00', 12),
(1, '2018-08-22 16:10:00', 12),
(2, '2018-08-22 14:00:00', 23);

-- Bus Prices

drop table if exists bus;
create table bus (
bus_id int,
timestamp timestamp without time zone,
price numeric
);

truncate table bus;
insert into bus
values

(12, '2018-08-22 00:10:00', 1.3),
(12, '2018-08-22 00:10:00', 1.5),
(12, '2018-08-22 00:20:00', 1.7),
(12, '2018-08-22 18:00:00', 2.0),
(13, '2018-08-22 00:00:00', 3.0);

最佳答案

我不知道这比您的解决方案(您没有展示)更快。相关子查询似乎是一个合理的解决方案。

但另一种方法是:

SELECT j.*, b.price
FROM journeys j LEFT JOIN
     (SELECT b.*, LEAD(timestamp) OVER (PARTITION BY bus_id ORDER BY timestamp) as next_timestamp
      FROM bus b
     ) b
     ON b.bus_id = j.bus AND
        j.timestamp >= b.timestamp AND
        (j.timestamp < b.next_timestamp OR b.next_timestamp IS NULL);

关于SQL:在第一个匹配行条件下连接 2 个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51975537/

相关文章:

mysql - 如何将数据库中两个表中的连接条目显示为 HTML 表?

MySQL:如何连接两个表的某些行不匹配

postgresql - 为什么我的 Kubernetes 服务运行在不同的子网上?

sql - 如何对 jsonb 中的字段执行求和,然后使用结果过滤查询的输出

java - PostgreSQL 找不到列

r - 我无法将 postgresql schema.table 与 dplyr 包连接

php - 通过 session 插入双客户 ID

sql - 两次加入同一个表以计算不同的列

sql - 我正在从数据库复制数据,如何知道首先从哪些表复制以避免引用错误?

postgresql - 如何识别禁用真空的表