2012-05-10 16 views
2

我有一个表中,有称为表A具有下列数据可乐T-SQL: - 在列,但只有这些

ColA 
100 
60 
50 
30 
10 
选择一个行,其中在一列中的值是等于,大于或小于

我有一个参数叫做@colA

我想只选择一行。条件是,如果ColA的值匹配@colA,则返回该行。如果找不到匹配项,那么它会查找ColA和@colA之间差异最小的行。

例如,如果@colA = 50,则返回包含50的行。如果@colA = 58,则返回具有60的行。如果@colA = 33,则返回包含30的行。如果@colA = 200,则返回100行。这可以通过在Select语句中使用Where子句和/或一些Min/Max语句来完成,还是用IF语句测试每个条件会更好?

感谢您的帮助!

+0

你可能想澄清为何33个返回30,而不是50。你约的话“其中的差别是最小的”令人困惑。我猜如果没有精确匹配,你想要的数字 - 或者更大或更小 - @colA和那个数字之间的绝对差异最小?关系(如果有的话)呢? – Pondlife

+0

33和30之间的差异小于33和50.如果ColA的值与colA不匹配,我总是希望ColA中的值大于colA的那一行。但是,ColA可能不会等于或大于colA。在这种情况下,我会选择ColA的值小于colA的那一行。无论colA的价值如何,总会有一排。 – AndroidDev

+0

我仍然感到困惑:你的评论基本上是这样说的:“如果有一个,我想要下一个最高的数字,否则下一个最低的”。所以33应该返回50,而不是30? – Pondlife

回答

0

这将在MS SQL Server 2008中完成。其他RDBMS需要进行调整。

CREATE TABLE #Test (Data int not null) 
INSERT #Test values (10), (30), (50),(60),(100) 


DECLARE @Target int = 40 

SELECT Data 
from (select 
      Data 
     ,row_number() over (order by abs(@Target - Data), sign(@Target - Data) desc) Ranking 
     from #Test) xx 
where Ranking = 1 

sign原因关系的rigamarole为正数被解析(即40返回竟被50,而不是30)。

+0

要在@Target = 40时选择50,我只使用了符号(数据 - @目标)。太感谢了。不知道标志功能。聪明的解决方案,绝对比IF语句更好。 – AndroidDev

0

试试这个:

DECLARE @ColA INT 
SELECT @ColA = 55 

SELECT TOP 1 @ColA + TA.CA FROM 
(
SELECT MIN(ColA) - @ColA AS CA FROM TableA WHERE ColA > @ColA 
UNION ALL 
SELECT MAX(ColA) - @ColA AS CA FROM TableA WHERE ColA < @ColA 
) AS TA 
ORDER BY ABS(TA.CA)