序言 我一直在调查一个概念,我在下面发布的内容是我一直在努力的简化版本.如果你看一下并且想"这样做没有任何意义"那么可能是因为我没有任何意义 - 可能有更有效的方法来做到这一点.我只想尝试一下,因为它看起来很有趣.
我正在尝试使用反向波兰式实现在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
Run Code Online (Sandbox Code Playgroud)
计算结果应该是123 ( = (100 * 1) + (10 * 2) + (1 * 3) ).
使用以下SQL(以及我编写的CLR函数ReversePolishAggregate和ToReversePolishArguments*),我可以得到正确的结果:
SELECT K
, dbo.ReversePolishAggregate(dbo.ToReversePolishArguments(Instruction, Amt))
FROM dbo.ReversePolishCalculation
GROUP BY K;
Run Code Online (Sandbox Code Playgroud)
问题 我想通过将指令和顺序放在一个单独的表中来更多地概括解决方案,以便我可以创建任意数据的计算.例如,我在考虑这样一个表:
Item | Type | Amount
-----+----------+-------
A | Budgeted | 10
A | Actual | 12
B | Actual | 20
B | Budgeted | 18
Run Code Online (Sandbox Code Playgroud)
并将其加入到这样的计算表中
Type | Instruction | Order
---------+-------------+------
Budgeted | Push | 1
Actual | Minus | 2
Run Code Online (Sandbox Code Playgroud)
计算每个项目是否超出或低于预算.重要的考虑因素是负数是非交换的,所以我需要指定顺序以确保从预算金额中减去实际金额,而不是相反.我希望我能够使用聚合ORDER BY子句中的OVER子句(然后稍微调整一下结果)来做到这一点.
SELECT K
, dbo.[ReversePolishAggregate](
dbo.[ToReversePolishArguments](Instruction, Amt))
OVER (PARTITION BY K ORDER by [Order])
FROM dbo.ReversePolishCalculation;
Run Code Online (Sandbox Code Playgroud)
但是我得到错误:
关键字"ORDER"附近的语法不正确.
我通过运行以下SQL语句检查了语法
SELECT K
, SUM(Amt) OVER (PARTITION BY K ORDER BY [Order])
FROM dbo.ReversePolishCalculation;
Run Code Online (Sandbox Code Playgroud)
这工作正常(它解析并运行,虽然我不确定结果是否有意义),所以我假设这是自定义CLR聚合或函数的问题.
我的问题这应该有用吗?是否有任何文件明确表示不支持此操作?我的语法合适吗?
我正在使用Visual Studio 2012 Premium,SQL Server Management Studio 2012和.NET framework 4.0.
*我创建了2个CLR函数作为解决方法,无法将多个参数传递到单个聚合函数中 - 请参阅本文.
编辑:这篇文章看起来不支持,但我希望有一些更正式的东西.
作为答案:
正式来自微软,没有.
它似乎没有进入2014年(或2016年CTP 3)...没有提及许多transact-sql更改:
http://msdn.microsoft.com/en-us/library/bb510411.aspx#TSQL