簡體   English   中英

使用Linq to SQL,如何在表中找到列的最小值和最大值?

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

我想找到一個最快的方法來獲得一個表中的列的最小值和最大值,其中只有一個Linq to SQL往返。 所以我知道這將在兩個往返中起作用:

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

我知道我可以使用group但是我沒有group by子句,我想聚合整個表! 如果沒有分組,我就不能使用.Min。 我試過這個:

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比它需要的更復雜。

那么,有沒有辦法只是得到正確的SQL?

編輯:這些家伙也失敗了: Linq to SQL:如何在沒有小組的情況下聚合? ......如果真的沒有答案,LINQ設計師的疏忽。

編輯2:我在SQL Server Management Studio執行計划分析中查看了我自己的解決方案(使用無意義的常量group by子句),它在我看來它與生成的計划完全相同:

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

因此,除非有人能夠提出一個更簡單或同樣好的答案,我想我必須將其標記為自己回答。 思考?

正如問題中所述,這種方法似乎實際上生成了最佳的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)  
} 

我只能發現這一個產生一些干凈的sql仍然沒有真正有效,相比於表中的select min(val),max(val):

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

還有另一個選項可以為最小和最大查詢使用單個連接(請參閱多個活動結果集(MARS)

或存儲過程..

我不知道如何將它翻譯成C#(我正在研究它)

這是Haskell版本

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

C#版本應該涉及Aggregate一些(我認為)。

LINQ to SQL查詢是單個表達式。 因此,如果您無法在單個表達式中表達您的查詢(或者您不喜歡它),那么您必須查看其他選項。

存儲過程,因為它們可以有語句,使您能夠在一次往返中完成此操作。 您將具有兩個輸出參數或選擇具有兩行的結果集。 無論哪種方式,您都需要自定義代碼來讀取存儲過程的結果。

(我個人認為沒有必要避免在這里進行兩次往返。這似乎是一種過早的優化,特別是因為你可能不得不跳過箍來使其運轉。更不用說你花費時間來證明這個決定的合理性了。並向其他開發人員解釋解決方案。)

換句話說:你已經回答了自己的問題。 “我不能先使用.Min而不首先進行分組”,然后是“那個瘋狂的群組條款似乎很愚蠢,它所制作的SQL比它需要的更復雜”,是簡單易懂的兩條線索 - 往返解決方案是您意圖的最佳表達(除非您編寫自定義SQL)。

您可以選擇整個表,並在內存中執行最小和最大操作:

var cache = // select *

var min = cache.Min(...);
var max = cache.Max(...);

根據數據集的大小,這可能是不多次訪問數據庫的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM