OVER 子句中的 SQL ORDER BY 与 CLR 聚合不兼容?

Posted

技术标签:

【中文标题】OVER 子句中的 SQL ORDER BY 与 CLR 聚合不兼容?【英文标题】:SQL ORDER BY within OVER clause incompatible with CLR aggregation? 【发布时间】:2014-06-11 14:42:41 【问题描述】:

序言 我一直在研究一个概念,我在下面发布的是我一直在尝试的缩减版。如果您看着它并认为“那样做没有任何意义”,那可能是因为我没有任何意义-可能有更有效的方法可以做到这一点。我只是想尝试一下,因为它看起来很有趣。

我正在尝试使用类似 Reverse-Polish 的实现在 SQL 中使用 CLR 自定义聚合来计算任意计算。我正在使用数据:

K | Amt | Instruction | Order
--+-----+-------------+------
A | 100 |        Push |     1
A |   1 |    Multiply |     2
A |  10 |        Push |     3
A |   2 |    Multiply |     4
A |     |         Add |     5
A |   1 |        Push |     6
A |   3 |    Multiply |     7
A |     |         Add |     8

计算的结果应该是123 ( = (100 * 1) + (10 * 2) + (1 * 3) )

使用以下 SQL(以及我编写的 CLR 函数 ReversePolishAggregateToReversePolishArguments*)可以得到正确的结果:

SELECT K
  , dbo.ReversePolishAggregate(dbo.ToReversePolishArguments(Instruction, Amt))
FROM dbo.ReversePolishCalculation
GROUP BY K;

问题 我想通过将指令和顺序放在单独的表中来更概括解决方案,以便我可以对任意数据进行计算。例如,我正在考虑这样的表格:

Item |     Type | Amount
-----+----------+-------
   A | Budgeted |     10
   A |   Actual |     12
   B |   Actual |     20
   B | Budgeted |     18

并将其加入到这样的计算表中

    Type | Instruction | Order
---------+-------------+------
Budgeted |        Push |     1
  Actual |       Minus |     2

计算每个项目是否超出或低于预算。重要的考虑因素是减号是不可交换的,因此我需要指定顺序以确保从预算金额中减去实际金额,而不是相反。我希望我能够使用聚合的 OVER 子句中的 ORDER BY 子句来做到这一点(然后再稍微调整一下结果)。

SELECT K
  , dbo.[ReversePolishAggregate](
    dbo.[ToReversePolishArguments](Instruction, Amt)) 
    OVER (PARTITION BY K ORDER by [Order])
FROM dbo.ReversePolishCalculation;

但是我得到了错误:

关键字“ORDER”附近的语法不正确。

我已经通过运行以下 SQL 语句检查了语法

SELECT K
  , SUM(Amt) OVER (PARTITION BY K ORDER BY [Order])
FROM dbo.ReversePolishCalculation;

这很好用(它会解析并运行,尽管我不确定结果是否有意义),所以我假设这是自定义 CLR 聚合或函数的问题。

我的问题这应该有效吗?是否有任何文档明确表示不支持此功能?我的语法对吗?

我正在使用 Visual Studio 2012 Premium、SQL Server Management Studio 2012 和 .NET framework 4.0。

* 我创建了 2 个 CLR 函数来解决无法将多个参数传递给单个聚合函数的问题 - 请参阅 this article。

编辑:This post 似乎不受支持,但我希望更正式一些。

【问题讨论】:

在您链接的帖子上,底部似乎有一个“官方”更新:“来自我的连接项的反馈(那是快速的......)是对 SQLCLR UDA 的窗口化'没有德纳利的剪辑。也许下一次。”。 在 SO 上查看这个答案:***.com/questions/22352026/… - 所以看起来你可以使用 OVER,但也许不能使用 ORDER by.... 你能把所有的减号替换为乘以 -1 和加号来解决这个问题吗? @NWest 是的,但是......它适用于加法和减法,但是对于更有趣的功能,如除法或提高幂,它可能不起作用。 仅供参考,鉴于从 SQL Server 2008 开始添加了对 UDA 的多个输入参数的支持,您无需创建额外的 SQLCLR UDF 和 UDT:technet.microsoft.com/en-us/library/ms182741.aspx 【参考方案1】:

作为答案:

微软官方,没有。

http://connect.microsoft.com/SQLServer/feedback/details/611026/add-support-for-over-order-by-for-clr-aggregate-functions

它似乎没有进入 2014 年(或 2016 年 CTP 3)...没有提及许多 transact-sql 更改:

http://msdn.microsoft.com/en-us/library/bb510411.aspx#TSQL

【讨论】:

正是我正在寻找的“更官方”的答案。谢谢

以上是关于OVER 子句中的 SQL ORDER BY 与 CLR 聚合不兼容?的主要内容,如果未能解决你的问题,请参考以下文章

order by 在 POSTGRESQL 中的 partition by 子句中不起作用?

优化 sum() over(order by...) 子句抛出“超出资源”错误

OVER ORDER BY 中的多个列

MySQL中带有Order By子句的Rank函数

SQL 错误“视图中的 ORDER BY 子句无效...”

简述SELECT语句中的FROM、WHERE以及ORDER BY子句的作用。SQL Server