【发布时间】:2017-08-16 14:24:05
【问题描述】:
我在 SQL Server 2012 中有一个这样的表:
CREATE TABLE [dbo].[CustomerLedgerEntries]
(
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[CustReference] [bigint] NOT NULL,
[DebitAmount] [decimal](18, 2) NOT NULL,
[CreationTime] [datetime] NOT NULL,
[Description] [nvarchar](512) NULL,
[ProductId] [nvarchar](32) NULL,
CONSTRAINT [PK_dbo.CustomerLedgerEntries]
PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY]
我想添加一个经过计算的持久列,该列将为我提供每个客户的运行余额。目前我使用这个查询来获取每个客户的流动余额:
SELECT
Id, CustReference, CreationTime, DebitAmount, CreditAmount,
SUM(DebitAmount - CreditAmount) OVER (PARTITION BY CustReference ORDER BY Id
ROWS UNBOUNDED PRECEDING) AS Balance
FROM
CustomerLedgerEntries
我尝试使用此查询添加计算列:
ALTER TABLE dbo.CustomerLedgerEntries
ADD Balance AS (SUM(DebitAmount - CreditAmount) OVER (PARTITION BY CustReference
ORDER BY Id
ROWS UNBOUNDED PRECEDING));
但是它会抛出一个错误:
消息 4108,第 15 级,状态 1,第 8 行
窗口函数只能出现在 SELECT 或 ORDER BY 子句中。
请问我怎样才能做到这一点?
编辑 1: 遵循下面@JM_ 的建议并创建 UDF 后,表格中的余额显示如下:
Id CusReference CreationTime DebitAmount CreditAmount Balance
30 3 2017-07-12 15:26:36.753 15000.00 0.00 14000.00
31 3 2017-07-12 15:26:36.753 0.00 1000.00 14000.00
而当我运行查询 Select Id, CustReference, CreationTime, DebitAmount, CreditAmount
, Sum(DebitAmount - CreditAmount) Over( Partition By CustReference Order by Id
rows Unbounded Preceding) As Balance
From CustomerLedgerEntries 时,结果正确显示:
30 3 2017-07-12 15:26:36.753 15000.00 0.00 15000.00
31 3 2017-07-12 15:26:36.753 0.00 1000.00 14000.00
差不多到了……但还没有完全到。请问有什么帮助吗?
【问题讨论】:
-
不支持您尝试执行的操作,因为计算列仅包含有关插入的行的信息..您可以创建视图
-
不支持,因为它不是确定性的。由于可以使用较早的 ID 添加新记录,导致该 ID 之后的所有记录,对于给定的 custReference,都将被重新评估;引擎无法更新超过这一记录。您要执行的操作在计算列中是不可能的。
-
在计算中使用 UDF 怎么样?
标签: sql-server tsql sql-server-2012