2016-09-14 116 views
1

我想查询数据库表,看起来像下面的简单的例子:Linq查询选择行,其中一列是一个最大值

Quote | Sequence | Item 
-------|-----------|----- 
    1 | 1.0M | a 
    1 | 2.0M | a 
    1 | 3.0M | a 
    1 | 1.0M | b 
    1 | 2.0M | b 
    1 | 3.0M | b 
    2 | 1.0M | x 
    2 | 2.0M | x 
    3 | 1.0M | y 

,我需要一个查询,得到所有行了鉴于Quote其中Sequence是该列的最大值:

Quote | Sequence | Item 
-------|-----------|----- 
    1 | 3.0M | a 
    1 | 3.0M | b 
    2 | 2.0M | x 
    3 | 1.0M | y 

我使用F#System.Data.Linq

我可以使用

let quoteQuery = 
    query{ 
     for row in db.[TABLE] do 
     select row 
     } 

得到所有行,但我不知道Linq不够好 - 然而 - 修改此有会产生预期的结果的查询。我试图使用the answer from this question来尝试修改我的查询,但是我试图修改(猜测?)必要的语法/语言。

有几个SQL的例子我能找到,但很少是LINQ的特异性。

+0

根据[文档](https://docs.microsoft。你应该可以使用'maxBy' ... –

+3

BTW,F#查询表达式不是* LINQ *;/*。他们是* F#查询表达式*。 –

回答

1

因为是在暗示评论,这不是LINQ的,但F#查询表达式。

这其实不是真正的这个问题是关于什么的毕竟。

它更集和关系代数。或东西...

那说:这里的事情是,如果按,然后让每个组的最大元素,那么你是好不错。请注意,示例代码不适用于任何数据库或其他方式,但这应该相当容易替换。

type Table = 
    { 
     Quote:int 
     Sequence: decimal 
     Item: string 
    } 

let createTableEntry (q,s,i) = 
    { 
     Quote = q 
     Sequence = s 
     Item = i 
    } 

let printTR {Quote=q;Sequence=s;Item=i} = printfn "%A | %A | %A" q s i 

let table = 
    [ 
     (1 , 1.0M , "a") 
     (1 , 2.0M , "a") 
     (1 , 3.0M , "a") 
     (1 , 1.0M , "b") 
     (1 , 2.0M , "b") 
     (1 , 3.0M , "b") 
     (2 , 1.0M , "x") 
     (2 , 2.0M , "x") 
     (3 , 1.0M , "y") 
    ] 
    |> List.map createTableEntry 

let result = 
    table 
    |> List.groupBy (fun x -> x.Quote, x.Item) //group "unique" by Quote&Item 
    |> List.map (fun x -> snd x |> List.max) //get max of each group, i.e. max of Sequence 


result |> Seq.iter printTR 

1 | 3.0M | "a" 
1 | 3.0M | "b" 
2 | 2.0M | "x" 
3 | 1.0M | "y" 

附录

后伊万Stoev已经部分回答了 “错误”。这里是一个“修正”版本,它不“相同”(不是真的一样,但是...),因为上面:

let quoteQuery = 
    query { 
     for row in table do 
     groupBy (row.Quote, row.Item) into g 
     let maxRow = 
      query { 
       for row in g do 
       sortBy row.Sequence 
       headOrDefault 
      } 
     select maxRow 
    } 

quoteQuery |> Seq.iter printTR 

附录II

既然编辑说,伊万的回答是不是真的一样的第一个代码示例,我还添加了一个是“如出一辙”与查询表达式:

let quoteQuery' = 
    query { 
     for row in table do 
     groupBy (row.Quote, row.Item) into g 
     let maxRow = 
      query { 
       for row in g do 
       maxBy row.Sequence 
      } 
     select (fst g.Key, maxRow, snd g.Key) 
    }|>Seq.map createTableEntry 

quoteQuery' |> Seq.iter printTR 
0

F#查询表达式被称为查询表达式,因为他们遵循(losely)LINQ查询语法( vs方法语法),他们确实实现了Linq.IQueriable。所以我也将它们视为LINQ。虽然它可能不符合惯用法,但上述查询可以用方法语法重写。如果你使用MoreLinq,那就很不起作用了。 “偷” 上表中从@HelgeReneUrholm定义:

open MoreLinq 

table 
    .GroupBy(fun x -> (x.Quote,x.Item)) 
    .Select(fun x -> x.MaxBy(fun x -> x.Sequence)) |> Seq.iter printTR 

1 | 3.0M | “a”
1 | 3.0M | “b”
2 | 2.0M | “x”
3 | 1.0M | “y” 的

相关问题