【问题标题】:Join on multiple columns and in one of the integer columns join by choosing minimum difference通过选择最小差异加入多个列并在其中一个整数列中加入
【发布时间】:2020-12-11 22:21:38
【问题描述】:

我有表 t1,我想在下面的 a、b 和 c 列上加入表 t2

+---------+---------+---------+
|a        |b        |c        |
+---------+---------+---------+
|473200   |1        |1.-1-1   |
|472400   |10       |1.-1-1   |
|472800   |10       |1.-1-1   |
|473200   |93       |1.-1-1   |
|472800   |26240    |1.-1-1   |
+---------+---------+---------+

t2

+---------+---------+---------+
|a        |b        |c        |
+---------+---------+---------+
|473200   |1        |1.-1-1   |
|472400   |10       |1.-1-1   |
|472800   |10       |1.-1-1   |
|473200   |93       |1.-1-1   |
|472800   |26250    |1.-1-1   |
+---------+---------+---------+

当我只加入 a 和 c 时,结果是

+---------+---------+---------+---------+
|t1.b     |t2.b     |a        |c        |
+---------+---------+---------+---------+
|93       |1        |473200   |1.-1-1   |
|1        |1        |473200   |1.-1-1   |
|10       |10       |472400   |1.-1-1   |
|10       |10       |472800   |1.-1-1   |
|26240    |10       |472800   |1.-1-1   |
|93       |93       |473200   |1.-1-1   |
|1        |93       |473200   |1.-1-1   |
|10       |26250    |472800   |1.-1-1   |
|26240    |26250    |472800   |1.-1-1   |
+---------+---------+---------+---------+

我试图实现的是将 b 列添加到“on”子句中,以便在 b 列的最小差异上进行连接。

想要的结果

+---------+---------+---------+---------+
|t1.b     |t2.b     |a        |c        |
+---------+---------+---------+---------+
|1        |1        |473200   |1.-1-1   |
|10       |10       |472400   |1.-1-1   |
|10       |10       |472800   |1.-1-1   |
|93       |93       |473200   |1.-1-1   |
|26240    |26250    |472800   |1.-1-1   |
+---------+---------+---------+---------+

我在这里看到了类似的东西

https://dba.stackexchange.com/questions/73804/how-to-retrieve-closest-value-based-on-look-up-table

但不知道如何申请我的案子。

【问题讨论】:

  • 在您的示例中,每个表中有两行 472800。如果有一个不相等的数字会发生什么?

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


【解决方案1】:

加入表格并计算列 c 的差异,然后使用 distinct on 以按差异排序的每个 (a, c) 仅返回一行。

with joined as (
  select t1.a, t1.c, t1.b as b1, t2.b as b2, t2.b - t1.b as b_diff
    from t1
         join t2 
           on t2.a = t1.a
          and t2.b = t1.b
          and t1.b <= t2.b
)
select distinct on (a, c) b1, b2, a, c
  from joined
 order by a, c, b_diff
;

【讨论】:

    【解决方案2】:

    一种选择是横向连接:

    select t1.*, t2.b b2
    from t1
    cross join lateral (
        select t2.*
        from t2
        where t2.a = t1.a and t2.c = t1.c
        order by abs(t2.b - t1.b)
        limit 1
    )
    

    另一种可能性是distinct on - 但您需要t1 的主键。假设 (a, c) 元组唯一标识 t1 中的每一行,你会去:

    select distinct on (t1.a, t1.c) t1.*, t2.b b2
    from t1
    inner join t2 on t2.a = t1.a and t2.c = t1.c
    order by t1.a, t1.c, abs(t2.b - t1.b)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-07
      • 2021-10-14
      • 2018-10-04
      • 1970-01-01
      • 2018-09-27
      • 1970-01-01
      • 2020-03-10
      • 1970-01-01
      相关资源
      最近更新 更多