一对一的选择限制 [英] one to one distinct restriction on selection

查看:122
本文介绍了一对一的选择限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了类似的问题。有两个表(x值的排序使
呈递增趋势!)

I encountered a problem like that. There are two tables (x value is ordered so that in a incremental trend !)

表A

    id     x
    1      1
    1      3
    1      4
    1      7

表B

    id     x
    1      2
    1      5

我想加入这两个表:

1)在id和

相等的条件下2)A的每一行应仅与B的一行匹配,反之(基于x的绝对差)(一对一关系)值(差异较小的行具有
的更高优先级进行匹配)。

I want to join these two tables:
1) on the condition of the equality of id and
2) each row of A should be matched only to one row of B, vice verse (one to one relationship) based on the absolute difference of x value (small difference row has more priority to match).

仅基于上面的描述并不清楚,因为如果两对行共享一个表中的同一行有相同的区别,没有办法确定哪个先行。因此,将A定义为主表,表A中行号较小的行始终排在最前面

Only based on the description above it is not a clear description because if two pairs of row which share a common row in one of the table have the same difference, there is no way to decide which one goes first. So define A as "Main" table, the row in table A with smaller line number always go first

演示的预期结果:

    id      A.x     B.x    abs_diff
    1       1       2      1
    1       4       5      1

表尾(由于一对一的规则,不应考虑A中的额外两行)

End of table(two extra rows in A shouldn't be considered, because one to one rule)

我正在使用PostgreSQL,所以我尝试过的事情是DISTINCT ON,但无法解决。

I am using PostgreSQL so the thing I have tried is DISTINCT ON, but it can not solve.

    select distinct on (A.x) id,A.x,B.x,abs_diff
    from
    (A join B
    on A.id=B.id)
    order by A.x,greatest(A.x,B.x)-least(A.x,B.x)

您有任何想法吗,在普通SQL中似乎很棘手。

Do you have any ideas, it seems to be tricky in plain SQL.

推荐答案

尝试:

select a.id, a.x as ax, b.x as bx, x.min_abs_diff
  from table_a a
  join table_b b
    on a.id = b.id
  join (select a.id, min(abs(a.x - b.x)) as min_abs_diff
          from table_a a
          join table_b b
            on a.id = b.id
         group by a.id) x
    on x.id = a.id
   and abs(a.x - b.x) = x.min_abs_diff

小提琴: http://sqlfiddle.com/#!15/ab5ae/5/0

尽管它与您的预期输出不匹配,但根据您的描述,我认为输出是正确的,因为您可以看到每对都有绝对的差异值1。

Although it doesn't match your expected output, I think the output is correct based on what you described, as you can see each pair has a difference with an absolute value of 1.

编辑-根据a到b的顺序尝试以下操作:

Edit - Try the following, based on order of a to b:

select *
  from (select a.id,
               a.x as ax,
               b.x as bx,
               x.min_abs_diff,
               row_number() over(partition by a.id, b.x order by a.id, a.x) as rn
          from table_a a
          join table_b b
            on a.id = b.id
          join (select a.id, min(abs(a.x - b.x)) as min_abs_diff
                 from table_a a
                 join table_b b
                   on a.id = b.id
                group by a.id) x
            on x.id = a.id
           and abs(a.x - b.x) = x.min_abs_diff) x
 where x.rn = 1

提琴: http:// sqlfiddle .com /#!15 / ab5ae / 19/0

这篇关于一对一的选择限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆