質問

I have an F# sql query which needs to sum two columns in each group.

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))
    }

I have not been able to find any examples of how to do this, however this code compiles fine, and by every indication, it should work. However when executing I always get an exception with this message "Could not format node 'New' for execution as SQL." If I remove data.losses everything works fine, but adding the second value causes an error. Is there another way to do this? Suggests would be appreciated.

Note, this question is similar, but handles the reverse situation in which multiple columns are grouped: groupby multiple columns in a F# 3.0 query

UPDATE:

I have also tried the following:

(NewAnonymousObjectHelper(T(data.earning, data.losses)))

where T is:

type T(earning : decimal, losses : decimal) =
    member val Earning=earning with get,set
    member val Losses=losses with get,set

However then a new Sum function would need to be created accepting the type T. I've also tried using MutableTuple from the F# PowerPack but failed to get it to recognize MutableTuple (not very familiar with this code/dll and associated namespaces). But it seems like it should work:

let t = MutableTuple<_,_>(item1=data.earning,item2=data.losses)
groupValBy t data.store into group

Maybe someone can offer a suggestion as to what I'm missing here.

CONCLUSION:

Looks like using let to sum results before the select is the way to go. Not clear why group.Sum() won't work on the select line. (Note: the error message I noted above my have resulted from some sql server problems.)

役に立ちましたか?

解決 2

Although I have to admit, I haven't tested this - I have a feeling something like this might work:

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) }

Inspired by the examples on this site. You might want to use sumByNullable instead.

他のヒント

This could be another solution using just groupBy but have only tested it with linq to objects.

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top