用于查找彼此接近的值的 SQL 语句
Posted
技术标签:
【中文标题】用于查找彼此接近的值的 SQL 语句【英文标题】:SQL statement to find values close to each other 【发布时间】:2015-06-05 19:28:54 【问题描述】:我正在努力定义 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 Server 完成这项工作会更有效率。这可能吗?
【问题讨论】:
SQL Server 的哪个版本?这可能会影响投注答案。此外,对于这种处理,SQL 不一定比加载列表和处理更有效。 这适用于 SQL Server v11.0。 【参考方案1】:尝试将表与自身连接:
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
【讨论】:
谢谢尼扎姆。这似乎很有希望,但是,它将列表限制为不同的值。就我而言,我需要所有彼此接近的值。 您可以使用子查询,例如SELECT * FROM @VALUES WHERE VALUE IN ( --- one of the suggested solutions --- )
。请看sqlfiddle.com/#!3/9eecb7db59d16c80417c72d1/482。【参考方案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,这可能更简洁,但可能不会影响性能:
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 中“更好”的类型。
【讨论】:
谢谢卡尔。这正是我一直在寻找的。当我在表中有多个值时,例如1, 1.25, 1.25, 2, 4, 4.5, 4.75, 5,结果是 1, 1.25, 1.25, 4.5, 4.75, 5。完美!【参考方案3】:试试这个;
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
【讨论】:
以上是关于用于查找彼此接近的值的 SQL 语句的主要内容,如果未能解决你的问题,请参考以下文章
sql语句更新字段里面的值,比方说 我要去掉某一列里面所有值的最后的一个字母(有空值)