我想查询一个类似下面简化示例的数据库表:
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 :(得分: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"
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的答案与第一个代码示例并不完全相同,我还添加了一个与查询表达式“完全相同”的答案:
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
答案 1 :(得分:0)
F#查询表达式被称为查询表达式,因为它们遵循(丢失)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 | “一”
1 | 3.0M | “B”
2 | 2.0M | “X”
3 | 1.0M | “y”