SQL查询用于查找具有常数的列值的最小差异

时间:2014-01-04 12:32:05

标签: sql sql-server

我有一张这样的表:

id  name  value
---------------    
1   one   20
2   two   30

我想写一个查询来查找它的值与常数28的绝对差值最小的行。

我该怎么做?!

提前致谢。

2 个答案:

答案 0 :(得分:1)

如果[Value]列上有索引,此解决方案应该提供良好的性能:

SET STATISTICS IO ON;

IF OBJECT_ID(N'dbo.MyDemoTable') IS NOT NULL
BEGIN
    DROP TABLE dbo.MyDemoTable;
END
GO

CREATE TABLE dbo.MyDemoTable (
    ID      INT IDENTITY(2,2) PRIMARY KEY,
    Name    SYSNAME,
    Value   INT 
);
INSERT dbo.MyDemoTable (Name,Value)
SELECT o.name, o.object_id FROM sys.objects o;

CREATE INDEX IX_MyDemoTable_Value ON dbo.MyDemoTable(Value);

DECLARE @Reference INT;
SET @Reference = 28;

SELECT TOP(1) *
FROM (
    SELECT xx.Value FROM (SELECT TOP(1) x.Value FROM dbo.MyDemoTable x WHERE x.Value <= @Reference ORDER BY x.Value DESC) xx
    UNION ALL
    SELECT yy.Value FROM (SELECT TOP(1) x.Value FROM dbo.MyDemoTable x WHERE x.Value > @Reference ORDER BY x.Value ASC) yy
) z(Value)
ORDER BY ABS(z.Value - 28) ASC;
GO

DROP TABLE dbo.MyDemoTable;

输出:

Value
-----------
28

Table 'MyDemoTable'. Scan count 2, logical reads 4

执行计划: enter image description here

答案 1 :(得分:0)

测试数据

DECLARE @t TABLE (id INT, value INT)
INSERT INTO @t
VALUES 
(1,20),(2,30),(3,40),(4,50),(5,60),(6,70),(7,100)

<强>查询

SELECT TOP 1 id  , Value, MIN(ABS(value - 28)) SmallestDiff
FROM @t 
GROUP BY id, Value
ORDER BY SmallestDiff

<强>结果

╔════╦═══════╦══════════════╗
║ id ║ Value ║ SmallestDiff ║
╠════╬═══════╬══════════════╣
║  2 ║    30 ║            2 ║
╚════╩═══════╩══════════════╝