具有自定义聚合函数的 F# 查询表达式

Posted

技术标签:

【中文标题】具有自定义聚合函数的 F# 查询表达式【英文标题】:F# query expression with a custom aggregate function 【发布时间】:2021-09-07 23:49:48 【问题描述】:

在我的项目中,我使用F# query expression 来查询我的数据库。

下面的代码计算按“键”列分组的平均值:

open System.Linq

query
    for row in ctx.MyTable do
    groupBy row.MyKey into g
    select (g.Key, g.Average(fun x -> x.MyValue))

我意识到对于我的项目来说,中位数比Average 更好。问题是似乎不支持在数据库引擎上计算中位数。但是,我想避免获取所有行并计算内存中的中位数,因为它们太多了,我需要节省网络带宽。

我可以在这里使用任何功能吗?或者我是否需要完全从头开始编写自己的方法(如果需要的话——如何)?

我的数据库引擎是 MSSQL,它包含一个 PERCENTILE_COUNT 函数,可能对我有用。另外,我使用 EntityFramework Core 3,我注意到它包含一些辅助功能,如 EF.Functions.DateDiffMinute,但我没有发现任何可以帮助解决我的问题。

【问题讨论】:

EF Core 当前不支持自定义聚合。如果你可以使用第三方扩展,我会告诉你用linq2db.EntityFrameworkCore @SvyatoslavDanyliv 继续 【参考方案1】:

我认为您不能使用 F# 查询表达式来执行此操作,但您始终可以在实体框架中下拉到原始 SQL。下面是一个计算 Northwind 数据库中每个客户订单金额中位数的示例:

ctx.Orders.FromSqlRaw(
    "select distinct \
    CustomerID, \
    percentile_cont(0.5) \
        within group (order by Freight) \
        over (partition by CustomerID) as FreightMedian \
    from Orders")

【讨论】:

以上是关于具有自定义聚合函数的 F# 查询表达式的主要内容,如果未能解决你的问题,请参考以下文章

为访问查询创建自定义聚合函数

加速自定义聚合函数

加速自定义聚合函数

SqlServer如何用Sql语句自定义聚合函数

60种特征工程操作:使用自定义聚合函数

SQL Server 中的自定义聚合函数 (concat)