如何使用linq C#获得最接近的最小数字

时间:2019-05-22 13:13:40

标签: c# linq

我有一个这样的sql表,

SomeDouble      SomeInt
1.00              121
1.50              124
2.00              200
2.50              321

依此类推... SomeDouble最多10,000

现在我可以在0.0到10,000.00之间有一个十进制数,我需要为其找到正确的行。例如,如果数字为1.12,那么我希望它返回121。

1.49应该返回121,1.50应该返回124,1.51应该返回124。

我正在尝试的修整版

var myValue = 1.12
var SomeInt = (from mainTable in table1
                        join table3 in table2 on mainTable.someId equals table3.someId
                        where table3.Column1 == Column1 && mainTable.SomeDouble >= myValue
                        select mainTable.SomeInt).FirstOrDefault();

但是我的输出是124。如何更改上面的值以获得比myValue最接近的最小数字?

5 个答案:

答案 0 :(得分:1)

在SQL中,您可以将最接近的表达式表示为:

select t.*
from t
order by abs(SomeDouble - 1.12)
fetch first 1 row only;

更有效的方法是将其首先缩小到两行:

select t.*
from ((select t.*
       from t
       where t <= 1.12
       order by SomeDouble desc
       fetch first 1 row only
      )  union all
      ((select t.*
       from t
       where t > 1.12
       order by SomeDouble asc
       fetch first 1 row only
      )
     ) t
order by (SomeDouble - 1.12)
fetch first 1 row only;

答案 1 :(得分:1)

使用Linq查询:

        var above = (from mainTable in table1
            join table3 in table2 on mainTable.someId equals table3.someId
            where table3.Column1 == Column1 && mainTable.SomeDouble >= myValue
            orderby mainTable.SomeDouble
            select new {SomeInt = mainTable.SomeInt, SomeDouble = mainTable.SomeDouble}).FirstOrDefault();

        var below = (from mainTable in table1
            join table3 in table2 on mainTable.someId equals table3.someId
            where table3.Column1 == Column1 && mainTable.SomeDouble < myValue
            orderby mainTable.SomeDouble descending 
            select new {SomeInt = mainTable.SomeInt, SomeDouble = mainTable.SomeDouble}).FirstOrDefault();

        int SomeInt;
        if (above == null)
            SomeInt = below.SomeInt;
        else if (below == null)
            SomeInt = above.SomeInt;
        else if (Math.Abs(below.SomeDouble - myValue) <= Math.Abs(above.SomeDouble - myValue))
            SomeInt = below.SomeInt;
        else 
            SomeInt = above.SomeInt;

答案 2 :(得分:1)

这是linq扩展方法,用于按SomeDouble的绝对差对记录进行排序,然后通过SomeInt按2个或更多匹配项中的最小顺序来获得最小记录,然后我们获得第一个记录。看来这两个列都存在于主表中,所以我想我们可以先限制它,然后再将您想要的任何内容加入。

mainTable.OrderBy(x => Math.Abs(x.SomeDouble - myValue)).ThenBy(x => x.SomeInt).First()

答案 3 :(得分:1)

由于SomeDouble的值是整数和半整数,因此可以将myValue舍入为下一个0.5的倍数:

var myValueToLookUp = Math.Ceiling(myValue * 2) / 2;

,然后直接使用SomeInt查找mainTable.SomeDouble == myValueToLookUp的值,以免与<=或> =引起混淆或效率低下。

答案 4 :(得分:0)

如果您可以使用SQL进行操作,那么

SELECT COALESCE(MAX(SomeInt), 0)
FROM DoubleToInt
WHERE SomeDouble <= 1.12