代码之家  ›  专栏  ›  技术社区  ›  Scott Stafford

使用linqtosql,如何在表中查找列的最小值和最大值?

  •  27
  • Scott Stafford  · 技术社区  · 14 年前

    我想找到一种最快的方法,通过一次Linq到SQL的往返来获得表中列的最小值和最大值。所以我知道这会在两次往返中起作用:

    int min = MyTable.Min(row => row.FavoriteNumber);
    int max = MyTable.Max(row => row.FavoriteNumber);
    

    我知道我可以用 group group by

    from row in MyTable 
    group row by true into r 
    select new { 
        min = r.Min(z => z.FavoriteNumber), 
        max = r.Max(z => z.FavoriteNumber) 
    }
    

    但是这个疯狂的组子句看起来很愚蠢,而且它生成的SQL比它需要的复杂得多。

    Linq to SQL: how to aggregate without a group by?

    编辑2:我在SQLServerManagementStudio执行计划分析中查看了我自己的解决方案(带有无意义的常量GROUPBY子句),在我看来,它与以下生成的计划相同:

    SELECT MIN(FavoriteNumber), MAX(FavoriteNumber)
    FROM MyTable
    

    5 回复  |  直到 7 年前
        1
  •  32
  •   Scott Stafford    14 年前

    如问题中所述,此方法似乎实际生成了最佳的SQL代码,因此尽管在LINQ中它看起来有点松松垮垮,但它应该是最佳性能方面的。

    from row in MyTable  
    group row by true into r  
    select new {  
        min = r.Min(z => z.FavoriteNumber),  
        max = r.Max(z => z.FavoriteNumber)  
    } 
    
        2
  •  6
  •   dh.    14 年前

    var r =
      (from min in items.OrderBy(i => i.Value)
       from max in items.OrderByDescending(i => i.Value)
       select new {min, max}).First();
    

    sql是

    SELECT TOP (1)
        [t0].[Value],
        [t1].[Value] AS [Value2]
    FROM
        [TestTable] AS [t0],
        [TestTable] AS [t1]
    ORDER BY
        [t0].[Value],
        [t1].[Value] DESC
    

    对于min和max查询,仍然有另一个使用单一连接的选项(请参见 Multiple Active Result Sets (MARS) )

    或存储过程。。

        3
  •  2
  •   Matt Ellen Bipin Vayalu    14 年前

    我还不知道如何把它翻译成C(我正在研究)

    这是哈斯克尔版本

    minAndMax :: Ord a => [a] -> (a,a)
    minAndMax [x]    = (x,x)
    minAndMax (x:xs) = (min a x, max b x)
                       where (a,b) = minAndMax xs
    

    Aggregate 我想是的。

        4
  •  1
  •   cllpse    14 年前

    您可以选择整个表,并在内存中执行最小和最大操作:

    var cache = // select *
    
    var min = cache.Min(...);
    var max = cache.Max(...);
    

    根据数据集的大小,这可能是避免多次访问数据库的方法。

        5
  •  1
  •   Bryan Watts    14 年前

    存储过程,因为它们可以有语句,使您能够在一次往返中完成这一点。您要么有两个输出参数,要么选择一个包含两行的结果集。无论哪种方式,您都需要自定义代码来读取存储过程的结果。

    (我个人认为没有必要避免两次往返。这似乎是一个过早的优化,特别是因为你可能需要跳转通过箍让它工作。更不用说你将花费多少时间来证明这个决定,并向其他开发人员解释解决方案。)

    换句话说:你已经回答了你自己的问题。”我不能在没有分组的情况下使用.Min”,然后是“疯狂的group子句看起来很愚蠢,它生成的SQL比它需要的更复杂”,这表明简单易懂的双向解决方案是您意图的最佳表达(除非您编写自定义SQL)。