参赛作品与其他人保持特定距离

时间:2013-05-09 19:28:23

标签: mysql sql sql-server distance

我的表有一个NAME和DISTANCE列。我想找出一种方法来列出来自同一名称的N个单位或更少内的所有名称。即鉴于:

NAME    DISTANCE
a   2
a   4
a   3
a   7
a   1
b   3
b   1
b   2
b   5

(假设N = 2) 我想

a 2 
a 4 
a 3
a 1
...
...
而不是     a2     a 2(因为它重复计算)

我正在尝试应用此方法,以便解决具有声明日期(存储为数字)的customerID,这些声明日期相互出现。我希望能够在同一客户的另一个索赔的10天内标记customerID和索赔日期。即,| a.claimdate - b.claimdate | < = 10.当我使用此方法时

WHERE a.CUSTID = b.CUSTID
AND a.CLDATE BETWEEN (b.CLDATE - 10 AND b.CLDATE + 10)
AND a.CLAIMID <> b.CLAIMID

我重复计算。 CLAIMID是独一无二的。

2 个答案:

答案 0 :(得分:2)

由于您不需要文本,只需要值,您可以使用DISTINCT完成此操作:

select distinct t.name, t.distance
from yourtable t
  join yourtable t2 on t.name = t2.name 
    and (t.distance = t2.distance+1 or t.distance = t2.distance-1)
order by t.name

SQL Fiddle Demo

根据您的修改,如果您要查找特定距离之间的结果,可以使用&gt; =和&lt; =(或BETWEEN):

select distinct t.name, t.distance
from yourtable t
  join yourtable t2 on t.name = t2.name 
    and t.distance >= t2.distance-1 
    and t.distance <= t2.distance+1
    and t.distance <> t2.distance
order by t.name

您需要添加t.distance <> t2.distance的最终条件,这样您就不会返回整个数据集 - 从技术上讲,每个距离都介于其间。如果您有一个要添加到连接的主键,这会更好,但如果不这样做,您也可以使用ROW_NUMBER()来获得相同的结果。

with cte as (
  select name, distance, row_number() over (partition by name order by (select null)) rn
  from yourtable
  )
select distinct t.name, t.distance
from cte t
  join cte t2 on t.name = t2.name 
    and t.distance >= t2.distance-1
    and t.distance <= t2.distance+1
    and t.rn <> t2.rn
order by t.name

Updated SQL Fiddle

答案 1 :(得分:1)

我喜欢@sgeddes'solution,但您也可以在连接条件中删除不同的or,如下所示:

select * from table a
where exists (
    select 1 from table b
    where b.name = a.name
        and b.distance between a.distance - 1 and a.distance + 1
)

这也确保了包含相等距离的行并考虑整个范围,而不仅仅是@HABO建议的距离差为n的行。