Linq查询以选择列为最大值的行
我想查询一个数据库表,它看起来像下面的简化示例:Linq查询以选择列为最大值的行,linq,f#,Linq,F#,我想查询一个数据库表,它看起来像下面的简化示例: 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 |
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 | 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还不太了解,无法修改它以生成所需结果的查询。我曾尝试使用来修改我的查询,但在尝试修改guess时遇到了麻烦?语法/语言是必需的
我可以找到几个SQL示例,但很少是特定于Linq的。正如注释中所暗示的,这不是Linq,而是f查询表达式 事实上,这并不是这个问题的真正含义 它更多的是集合代数和关系代数。或者别的什么 这就是说:这里的问题是,如果你分组,然后得到每个组的最大元素,那么你就是从好到好。请注意,示例代码不适用于任何DB或其他类型,但这应该很容易替换
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"
补遗
在伊万·斯托夫回答部分错误之后。这是一个修正的版本,它做的是相同的,不是真的相同,但是。。。如上所述:
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
增编二
由于我编辑并说Ivans answer与第一个代码示例并不完全相同,因此我还添加了一个与查询表达式完全相同的示例:
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
F查询表达式之所以称为查询表达式,是因为它们很少遵循LINQ查询语法而不是方法语法,并且它们确实实现了LINQ.IQuerable。所以我也认为他们是林克。虽然上面的查询可能不惯用,但可以用方法语法重写。如果你想了解更多,那就相当简洁了。从@helgeneuroholm中窃取上表定义:
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
根据您应该能够使用maxBy…顺便说一句,F查询表达式不是LINQ;它们是F查询表达式。