【问题标题】:Select rows with minimum difference选择差异最小的行
【发布时间】:2011-05-20 03:05:23
【问题描述】:

我很擅长 SQL,但我想不出解决这个“相似”数据分析问题的好方法:

给定一个包含一组整数的表,我需要将每个整数与第二个表中最相似(最小绝对差)的整数进行匹配。通常我会根据数字的差异进行笛卡尔连接和排序,但我只需要为每个表中的每一行获取一个配对,因此任何一个表中的值都不能使用两次。

知道如何做到这一点吗?

编辑:示例:

TABLE_A

34
57
108
219
380
5000

TABLE_B

4000
200
400
99
40
33
34
4600

配对将是 table_a 中的一行和 table_b 中最接近的行:

结果

34,34
57,40
108,99
219,200
380,400
5000,4600

因此,任何一个表中的行都不会出现两次。

编辑:更多说明:我正在尝试解决这个问题,在给定 table_a 的 1 行的情况下,我们从 table_b 中找到最接近的 1 行。那变成一对并被删除。然后从 table_a 中取出下一行并重复。因此,我们试图为每一行找到最佳匹配并优化该配对,而不是试图优化总差异。

【问题讨论】:

  • "...每个表中的每一行都有一个 pariting..." 令人困惑。是“取第一个表中的每个值并在第二个表中找到最接近的值”吗?或者是否有一些要求第二个表中的每个值都必须出现在列表中,或者必须出现在最终集合中?也许一个小例子会有所帮助
  • 您能否添加示例数据以帮助我们可视化输入和输出?我们可以假设整数在每个表中都是唯一的吗?一张桌子上有 5 和 7,另一张桌子上有 6 呢? 6 应该出现两次,因为它同样接近 5 和 7
  • 如果您正在寻找集合之间总差异最小的解决方案,那么如果您在一个表中有 5 和 8,在第二个表中有 7 和 15,那么您的集合实际上是 ( 5,7), (8,15)。即使最小的差异在 7 和 8 之间也是如此。因为 ((7-5) + (15-8)) == 9 但 ((8-7)+(15-5) == 11。所以为该行找到最接近数字的解决方案不一定是数据集的最佳解决方案。我们确实需要知道您希望如何确定解决方案的优先级并解决 gbn 提到的冲突/重复。

标签: sql


【解决方案1】:

假设

如果给定 table_a 的 1 行,我们会找到 table_b 中最接近的 1 行

select
   *
from
   TABLE_A a
   cross apply
   (select top 1 Number from TABLE_B b order by abs(b.Number - a.Number)) b2

这也假设 b 中的行可以重复:尝试一下,看看它是否符合您的要求。但是,这应该适合您的示例数据,以便回答您的​​问题...

【讨论】:

    【解决方案2】:
    select v.*
    from
    
       (select a.value as avalue, b.value as bvalue,
       (abs(a.value - b.value)) as difference 
       from 
       TABLE_A a,
       TABLE_B b) v,
    
       (select a.value as avalue, b.value as bvalue,
       min((abs(a.value - b.value))) as difference 
       from 
       TABLE_A a,
       TABLE_B b
       group by a.value, b.value) m
    
    where m.avalue = v.avalue and m.bvalue = v.value and m.difference = v.difference
    

    【讨论】:

      【解决方案3】:

      您可能需要使用光标来处理这个问题。将每个表中的数据复制到它们自己的临时表中,并一次一行地应用您的逻辑。

      如果没有游标的话,这很困难,如果不是不可能的话,是因为您处理第一个表中每个数字的顺序会影响最终结果。

      如果你的第一个表是这样的

      9
      10
      

      你的第二张桌子看起来像这样

      5
      6
      

      那么如果你先处理 9,你的结果会是这样的

      9,6
      10,5
      

      如果您先处理 10 个,结果将如下所示

      10,6
      9,5
      

      【讨论】:

        猜你喜欢
        • 2011-04-20
        • 1970-01-01
        • 2019-04-07
        • 2012-10-09
        • 1970-01-01
        • 1970-01-01
        • 2016-01-15
        • 1970-01-01
        • 2012-04-11
        相关资源
        最近更新 更多