我在SQL Server 2012中有一个表,如下所示:
import {Container, Content, Text} from 'native-base';
我想添加一个计算的,持久的列,它将为我提供每个客户的运行余额。目前,我使用此查询来获取每个客户的运行余额:
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
但它引发了一个错误:
Msg 4108,Level 15,State 1,Line 8
窗口函数只能出现在SELECT或ORDER BY子句中。
我怎样才能做到这一点?
编辑1: 按照以下@JM_建议并创建UDF后,在表格中,余额显示如下:
ALTER TABLE dbo.CustomerLedgerEntries
ADD Balance AS (SUM(DebitAmount - CreditAmount) OVER (PARTITION BY CustReference
ORDER BY Id
ROWS UNBOUNDED PRECEDING));
然而,当我运行查询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
所以差不多......但不是那里。请帮忙吗?
答案 0 :(得分:1)
我假设您的表有一个信用列,但上面的脚本没有包含它。您可以使用UDF执行此操作:
- 编辑:
CREATE FUNCTION [dbo].[UDF_GetBalance] (@CustRef bigint, @ID bigint)
RETURNS decimal(18,2)
AS
BEGIN
DECLARE @Balance decimal(18,2)
SELECT @Balance = SUM(DebitAmount - CreditAmount) OVER (PARTITION BY CustReference ORDER BY Id
ROWS UNBOUNDED PRECEDING)
FROM
CustomerLedgerEntries WHERE CustReference =@CustRef and ID <= @id
RETURN @Balance
END
ALTER TABLE CustomerLedgerEntries ADD Balance as (dbo.UDF_GetBalance(CustReference, ID))
答案 1 :(得分:1)
在计算列中使用标量udf这是一个糟糕的想法,原因有很多。一个巨大的问题是,即使未引用计算列,对该表的查询也将以串行方式运行。这是一篇很棒的文章,解释了为什么你不想这样做:Another reason why scalar functions in computed columns is a bad idea
SQL Server 2012提供了索引builds/rebuilds in parallel的功能,但是当您以这种方式使用标量udf时,您将失去该功能。您可以使用this article中引用的traceflag自行测试。
标量函数也有许多其他原因。为了获得限制CustomerLedgerEntries表上串行执行的最佳性能,我将使用iTVF(请注意,我无法对此进行测试)。 iTVF允许您使用 所有 您的CPU。
CREATE FUNCTION dbo.UDF_GetBalance (@CustRef bigint)
RETURNS TABLE AS RETURN
SELECT balance = SUM(DebitAmount - CreditAmount)
OVER (PARTITION BY CustReference ORDER BY Id ROWS UNBOUNDED PRECEDING)
FROM CustomerLedgerEntries
WHERE CustReference =@CustRef;
GO