我有一个F#sql查询,需要在每个组中加总两列。
let financials = query{
for data in dbData do
groupValBy (data.earning, data.losses) data.store into group
select (group.Key, group.Sum(fun (group) -> fst group), group.Sum(fun (group) -> snd group))
}
我无法找到任何如何执行此操作的示例,但是此代码编译良好,并且通过每个指示,它应该工作。但是在执行时,我总是得到一条例外消息“无法格式化节点'新'作为SQL执行。”如果我删除data.losses一切正常,但添加第二个值会导致错误。还有另一种方法吗?建议将不胜感激。
注意,这个问题类似,但处理了多列被分组的相反情况:groupby multiple columns in a F# 3.0 query
更新:
我也尝试了以下内容:
(NewAnonymousObjectHelper(T(data.earning, data.losses)))
其中T为:
type T(earning : decimal, losses : decimal) =
member val Earning=earning with get,set
member val Losses=losses with get,set
然而,需要创建一个接受类型T的新Sum函数。我也尝试过使用F#PowerPack中的MutableTuple但是没能让它识别MutableTuple(不熟悉这个代码/ dll和相关的命名空间) )。但它似乎应该有效:
let t = MutableTuple<_,_>(item1=data.earning,item2=data.losses)
groupValBy t data.store into group
也许有人可以提出我在这里缺少的建议。
结论:
在使用select之前,看起来像使用let来对结果求和。不清楚为什么group.Sum()不能在选择行上工作。 (注意:我上面提到的错误消息是由于某些sql server问题造成的。)
答案 0 :(得分:3)
这可能是仅使用groupBy的另一种解决方案,但仅使用linq对象进行测试。
type Data =
{Store : string; Earning : float; Losses : float }
let dbData =
[| { Store = "Store A"; Earning = 5.0; Losses = 2.0 }
{ Store = "Store A"; Earning = 10.0; Losses = 3.0 }
{ Store = "Store B"; Earning = 3.0; Losses = 1.0 } |]
let financials =
query {
for data in dbData do
groupBy data.Store into group
let earnings = query { for g in group do sumBy g.Earning }
let losses = query { for g in group do sumBy g.Losses }
select (group.Key, earnings, losses) } |> Seq.toArray
答案 1 :(得分:2)
虽然我不得不承认,我还没有测试过这个 - 我觉得这样的事情可能有用:
let financials =
query {
for data in dbData do
groupValBy (data.earning, data.losses) data.store into group
let earnings = query { for (e,_) in group do sumBy e }
let losses = query { for (_,l) in group do sumBy l }
select (group.Key, earnings, losses) }
受到this site上的例子的启发。您可能希望改为使用sumByNullable
。