存储过程/功能逻辑,用于汇总帐户余额

时间:2014-10-07 07:24:54

标签: sql oracle stored-procedures

Version B       C       D       output  Account number  Balance
----------------------------------------------------------------
2       1283    1303    0       4071    1                10
2       1283    1304    0       4072    2                20
3       1283    4068    1303    4071    1                30
3       1283    4069    1304    4072    4                40
4       1283    4071    4068    4071    5               -50
4       1283    4072    4069    4072    2                90

版本,B,C,D是all_details表中的列。列“输出”是我希望实现的所需输出,我希望将所有上述列存储在表中,直到输出

如何在输出的第一行中放置4071

1) i took 1303 in column C and then looked into column D
2) then it is again referring to 4068 in column C 
3) Then i took 4068 and it is refering to 4071 in column C its like a linkage

我正在使用B列,因为它是与其他列相关的信息。

我需要另一个列输出,以便我可以识别相关链接并总结余额。例如

我将总结相关链接1303,4068,4071余额分组输出我将获得10 + 40 = 50帐户1和-50帐户5对应4071

1 个答案:

答案 0 :(得分:1)

因此,根据我的理解,您需要有一些递归查找给定数字的最后一个链接数字的内容。这些链接存在于您的Column CColumn D之间 我假设B列是分组类型编号,但我确信您可以弄清楚如何调整函数以返回您需要返回的内容。

您需要做的是构建一个SQL function,它将遍历您的表并按照链接进行操作,直到找不到更多链接。下面将详细介绍如何做到这一点。

首先建立样本数据,就像你提出的那样(注意这会在你的数据库上创建一个表,小心!

-- Building testing data
if exists (select 1
             from sys.objects
            where name = 'versionhistory'
              and type = 'U')
begin
  drop table versionhistory
end

create table versionhistory
      ( versionno  int,
        colB       int,
        colC       int,  -- Current Value
        colD       int ) -- Previous value

insert versionhistory
     ( versionno,
       colB,
       colC,
       colD )
values -- B     C     D
     ( 2, 1283, 1303, 0),
     ( 2, 1283, 1304, 0),
     ( 3, 1283, 4068, 1303),
     ( 3, 1283, 4069, 1304),
     ( 4, 1283, 4071, 4068),
     ( 4, 1283, 4072, 4069)
go

现在我们需要创建将遍历表记录的函数,按照两列之间的链接,直到它找不到更多链接,然后返回最后一个链接值。

-- Create the function that will get the last entry for a give number
if exists (select 1 from sys.objects where name = 'f_get_last_ver' and type = 'FN')
begin
  drop function f_get_last_ver
end
go
create function f_get_last_ver
     ( @colB int,
       @colC int )
  returns int
  as
  begin
    declare @nextColC int,
            @lastColC int

    -- Initial check if there is a 'next' version
    select @nextColC = isnull((select vh.colC
                                 from versionhistory vh
                                where vh.colB = @colB
                                  and vh.colD = @colC), 0)

    -- This will handle the loop until there are no more entries linked
    while isnull(@nextColC, 0) <> 0
    begin
      -- Store our last value for return purposes
      select @lastColC = @nextColC

      -- Get our next version number that is linked
      select @nextColC = isnull((select vh.colC
                                   from versionhistory vh
                                  where vh.colB = @colB
                                    and vh.colD = @nextColC), 0)
    end

    -- Return our last value, otherwise if no linkage was found, return the input
    return isnull(@lastColC, @colC)
  end
go

最后,您可以使用该功能。

-- Example usage
select dbo.f_get_last_ver(1283, 1303), -- returns 4071
       dbo.f_get_last_ver(1283, 1304)  -- returns 4072

在完成测试/试验

时,请记得清理数据库

我希望函数内部的注释能够解释发生的事情,但是如果有什么不清楚的地方,请求离开。

PS 请将实际代码中的列和变量重命名为更有意义的列名和变量,因为B,C,D并没有真正解释它们的用途。