【问题标题】:Join 2 tables and keep only the first closest event加入 2 个表并仅保留第一个最近的事件
【发布时间】:2019-12-12 14:51:38
【问题描述】:

我有以下当前表格:

table_1
id | timestamp | origin | info

table_2
id | timestamp | origin | type

我的目标是为表 2 中的每一行找到表 1 中的原始事件。我只想保留第一个。 例如:

table 1
1 | 1000 | "o1" | "i1"
2 | 2000 | "o2" | "i2"
3 | 2010 | "o2" | "i2"

table 2
1 | 1010 | "o1" | "t1"
2 | 2100 | "o2" | "t2"

我的预期结果是:

table_2.id | table_2.timestamp | table_2.origin | table_2.type | table_1.info | table_1.timestamp
1          | 1010              | "o1"           | "t1"         | "i1"         | 1000
2          | 2100              | "o2"           | "t2"         | "i2"         | 2010

目前我只是在 origintable_2.timestamp > table_1.timestamp 上使用简单的连接,这给了我:

table_2.id | table_2.timestamp | table_2.origin | table_2.type | table_1.info | table_1.timestamp
1          | 1010              | "o1"           | "t1"         | "i1"         | 1000
2          | 2100              | "o2"           | "t2"         | "i2"         | 2000
2          | 2100              | "o2"           | "t2"         | "i2"         | 2010

如您所见,我不想要上面的第二行,因为我只想要 table_1 中第一个最近的事件。

有什么想法吗?

【问题讨论】:

    标签: sql postgresql join greatest-n-per-group


    【解决方案1】:

    跨数据库的解决方案是使用相关子查询进行连接和过滤:

    select 
        t2.*,
        t1.info,
        t1.timestamp t1_timestamp
    from 
        table_2 t2
        inner join table_1 t1
            on t1.origin = t2.origin
            and t1.timestamp = (
                select max(t11.timestamp) 
                from table_1 t11
                where t11.origin = t2.origin and t11.timestamp < t2.timestamp
            )
    order by t2.id
    

    由于您使用的是 Postgres,您可以使用方便的语法distinct on;这实际上可能表现更好:

    select 
        distinct on(t2.id)
        t2.*,
        t1.info,
        t1.timestamp t1_timestamp
    from 
        table_2 t2
        inner join table_1 t1 
            on t1.origin = t2.origin and t1.timestamp < t2.timestamp
    order by t2.id, t1.timestamp desc
    

    Demo on DB Fiddle - 两个查询都产生:

    编号 |时间戳 |产地 |类型 |信息 | t1_timestamp -: | --------: | :----- | :--- | :--- | ------------: 1 | 1010 | o1 | t1 | i1 | 1000 2 | 2100 | o2 | t2 | i2 | 2010

    【讨论】:

    • 感谢您的回答和发现 Db Fiddle。
    猜你喜欢
    • 2020-11-07
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2022-06-27
    • 2020-12-24
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多