F#查询,按单列分组多个值

时间:2014-03-12 18:13:12

标签: types f# provider

我有一个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问题造成的。)

2 个答案:

答案 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