Using Linq to SQL, how do I find min and max of a column in a table?

前端 未结 5 1224
情书的邮戳
情书的邮戳 2020-12-29 03:40

I want to find the fastest way to get the min and max of a column in a table with a single Linq to SQL roundtrip. So I know this would work in two roundtrips:



        
相关标签:
5条回答
  • 2020-12-29 03:59

    A LINQ to SQL query is a single expression. Thus, if you can't express your query in a single expression (or don't like it once you do) then you have to look at other options.

    Stored procedures, since they can have statements, enable you to accomplish this in a single round-trip. You will either have two output parameters or select a result set with two rows. Either way, you will need custom code to read the stored procedure's result.

    (I don't personally see the need to avoid two round-trips here. It seems like a premature optimization, especially since you will probably have to jump through hoops to get it working. Not to mention the time you will spend justifying this decision and explaining the solution to other developers.)

    Put another way: you've already answered your own question. "I can't use the .Min without grouping first", followed by "that crazy group clause seems silly, and the SQL it makes is more complex than it needs to be", are clues that the simple and easily-understood two-round-trip solution is the best expression of your intent (unless you write custom SQL).

    0 讨论(0)
  • 2020-12-29 04:03

    I'm not sure how to translate it into C# yet (I'm working on it)

    This is the Haskell version

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

    The C# version should involve Aggregate some how (I think).

    0 讨论(0)
  • 2020-12-29 04:09

    You could select the whole table, and do your min and max operations in memory:

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

    Depending on how large your dataset is, this might be the way to go about not hitting your database more than once.

    0 讨论(0)
  • 2020-12-29 04:15

    As stated in the question, this method seems to actually generate optimal SQL code, so while it looks a bit squirrely in LINQ, it should be optimal performance-wise.

    from row in MyTable  
    group row by true into r  
    select new {  
        min = r.Min(z => z.FavoriteNumber),  
        max = r.Max(z => z.FavoriteNumber)  
    } 
    
    0 讨论(0)
  • 2020-12-29 04:18

    I could find only this one which produces somewhat clean sql still not really effective comparing to select min(val), max(val) from table:

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

    the sql is

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

    still there is another option to use single connection for both min and max queries (see Multiple Active Result Sets (MARS))

    or stored procedure..

    0 讨论(0)
提交回复
热议问题