【问题标题】:Stored Procedure/Function Logic for Summing of account balances账户余额求和的存储过程/函数逻辑
【发布时间】:2014-12-01 13:33:45
【问题描述】:
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

Version,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 balances Group by Output 我会得到 10+40 = 50 账户 1 和 -50 账户 5 对应 4071

【问题讨论】:

  • 您的查询是什么?什么是表结构?请补充一些信息,现在还不清楚。
  • 我无法格式化,请编辑查看结构
  • 解释你的数据的含义。我们看到的是一堆乱七八糟的无用数字。
  • 这是一个困难的,因为你需要循环找到最高的。我不确定这是否可以通过 SQL 语句来完成。
  • 我认为您必须将数字视为版本号。列 C 和 D 关联为连续版本,C 为当前版本,D 为先前版本。所以如果你看到版本 1303 有前任 0,那么之前没有版本。但是 4068 版本是 1303 的后继版本。而 4071 是 4068 的后继版本。4071 没有更高版本,因此 4071 的结果应该是 4071 以及它的所有前辈。

标签: sql oracle stored-procedures


【解决方案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

完成测试/实验后记得清理数据库

我希望函数内的 cmets 能够充分解释正在发生的事情,但如果有不清楚的地方,请询问。

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

【讨论】:

  • 但我正在考虑如何在选择查询中编写而不编写存储过程/函数。无论如何感谢您的时间和解释
  • 以上只是一个例子,实际表格包含大量数据。只是为了掩蔽我使用了 a.b.c.d 约定
  • 通过一个函数,sql server 可以有效地优化它。我也使用过这种方法来查找包含数百万条记录的速率,因此它的速度非常高效。不幸的是,不会有一个正在运行的查询(我知道)能够在没有某种循环的情况下跟踪这样的链接。
  • 我理解,但只是想发布是否可以通过 Select 查询,因为我的系统限制要在 Select 查询中写入逻辑,否则我必须为其创建一个表来存储存储过程的结果/函数只是为了避免它我试图在选择查询中写
猜你喜欢
  • 2017-03-07
  • 2015-06-24
  • 2011-07-11
  • 2014-12-15
  • 2012-04-07
  • 2016-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多