用于查找彼此接近的值的SQL语句

时间:2015-06-05 19:28:55

标签: sql sql-server sql-server-2012

我正在努力定义SQL以查找统计上彼此接近的值列表。例如,我们假设我们有一张价格表,我希望所有价格相差0.25美元以内。

价格: 1.00 1.25 2.00 4.00 4.50 4.75 5.00

对于上面的例子,它应该返回1.00,1.25,4.50,4.75和5.00,因为它们在列表中另一个值的0.25之内。

我不想获得原始列表,然后在代码中处理它。 SQL服务器完成这项工作会更有效率。这可能吗?

3 个答案:

答案 0 :(得分:5)

尝试连接表格:

declare @Values table (value float)
insert into @Values values (1),(1.25),(2),(4),(4.5),(4.75),(5)

select distinct A.Value
from @values A
inner join @Values B
    on abs(A.value - B.Value) <= 0.25
    and A.Value <> B.Value

SQL Fiddle

或者在另一种方法中,使用CROSS APPLY

SELECT DISTINCT CASE WHEN N.n=1 THEN A.Value ELSE ant END
FROM @Values A
cross apply (select max(value) from @Values where Value < A.Value) B(ant)
CROSS APPLY(SELECT 1 UNION SELECT 2)N(n)
where abs(A.value - ant) <= 0.25

SQL Fiddle

而且,如果您使用的是SQL Server 2012+,则可以使用LEAD函数:

SELECT DISTINCT CASE WHEN N.n=1 THEN A.Value ELSE ant END
FROM (
    SELECT Value, 
        LEAD(Value, 1,0) OVER (ORDER BY Value) AS Ant
    FROM @Values
) A
CROSS APPLY(SELECT 1 UNION SELECT 2)N(n)
where abs(Ant - Value) <= 0.25

SQL Fiddle

答案 1 :(得分:2)

我可能会使用相关的子查询:

DECLARE @tbl TABLE (val DECIMAL (9,2))
INSERT INTO @tbl VALUES (1),(1.25),(2),(4),(4.5),(4.75),(5)

SELECT * 
  FROM @tbl a 
 WHERE EXISTS(SELECT 1 
                FROM @tbl b 
               WHERE     b.val <> a.val 
                     AND b.val BETWEEN a.val-.25 AND a.val+.25)

你也可以在ABS中使用ABS,这可能更简洁,但可能不会影响性能:

SELECT * 
  FROM @tbl a 
 WHERE EXISTS(SELECT 1 
                FROM @tbl b 
               WHERE     b.val <> a.val 
                     AND ABS(b.val - a.val) <= .25)

编辑:我从Float切换到Decimal,因为这是SQL Server中的“更好”类型。

答案 2 :(得分:0)

试试这个;

DECLARE @TBL TABLE (Nums float)

insert into @TBL values (1),(1.25),(2),(4),(4.5),(4.75),(5);

WITH CTE AS(
Select  t1.Nums as T1,t2.Nums as T2 From @TBL t1
CROSS JOIN @TBL t2)
Select  distinct ct.T1 From CTE ct
where abs(ct.T1 - ct.T2) = 0.25
order by ct.T1