2013-05-09 59 views
0

我的桌子有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 
... 
... 

代替 2(因为双数)

我想应用此方法来解决具有索赔日期(以数字形式存储)的客户ID,这些索赔日期以彼此簇集的形式出现。我希望能够标记客户ID以及同一客户发出的另一个索赔要求的10天内的索赔日期。即| 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是独一无二的。

+0

你使用的是mysql吗?或SQL服务器? – 2013-05-09 19:28:56

+0

使用microsoftSQL,但mysql语法将是伟大的 – 2013-05-09 19:31:23

回答

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

鉴于您的编辑,如果你正在寻找之间的结果有一定的距离,你可以使用> =和< =(或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 

您需要添加01最终标准所以你不返回整个数据集 - 技术上每个距离都在它自己之间。如果你有一个主键添加到连接中,这会更好,但如果你不这样做,你也可以利用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

+0

不知道这是否在性能上有很大的不同,但我会用(t2.distance + 1,t2.distance - 1)中的'和t.distance替换'或' ',主要是为了可读性。 – dang 2013-05-09 19:42:32

+1

我认为这个问题意味着距离'N'可以作为输入提供。如果是这种情况,那么距离就需要变化,而不是“IN”。 – HABO 2013-05-09 19:46:11

+0

好点,[@HABO](http://stackoverflow.com/users/92546/habo)。在[我自己的回答]中考虑了这一点(http://stackoverflow.com/a/16469879/1815558)。 – dang 2013-05-09 19:48:16

1

我喜欢@sgeddessolution,但你也可以在连接状态下摆脱了独特和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 
) 

这也保证了平等的行距离包括在内,并考虑整个范围,而不仅仅是距离差值恰好为n的行,如@HABO所示。

+1

我喜欢你要去的地方,但是你也需要添加标准来检查自己。这就是我的意思(http://sqlfiddle.com/#!3/4c89f/2)。这会返回不正确的结果。你可以通过引入ROW_NUMBER()来解决这个问题。或者从技术上讲,您可以添加和a.distance <> b.distance,但对于具有相同距离的不同行,这不是一个好的解决方案。不错的用法虽然存在 - +1 – sgeddes 2013-05-09 20:57:15

+0

很难区分没有PK或唯一列的行。我想你可以用一个标识列创建一个表变量或临时表,然后比较它们,包括子查询中的'和a.id <> b.id'。 – dang 2013-05-09 21:37:56