我正在努力定义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服务器完成这项工作会更有效率。这可能吗?
答案 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
或者在另一种方法中,使用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 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
答案 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