【问题标题】:SQL, How to subtract from previous left over amounts, CTE? [closed]SQL,如何从以前的剩余金额中减去 CTE? [关闭]
【发布时间】:2018-10-06 02:04:05
【问题描述】:

我需要帮助才能访问此图像的“已拍摄”和“左侧”列。我尝试了 CTE 和滞后功能,但似乎没有任何效果。

如果我有一个表中的前四列,我该如何计算 'Taken' 和 'left' 列。

基本上,'Taken' 和 'left' 的方式基本上是针对每个组的,我们有一个最大限制,可以从中取出第 4 列。它们必须按照A、B、C、D的顺序取出

如果有问题请告诉我,我会尽力回答。

谢谢

由于人们要求给定的记录集。这就是它的样子。我需要找出列“采取”和“离开”的逻辑

Accountno   GroupName   MaxGroup    Amount
101          A          70           0
101          B          70           50
101          C          70          0
101          D          70          20
102          A          95          30
102          B          95           0
102          C          95           5
102          D          95           10
103          A          80           40
103          B          80          15
103          C          80          10
103          D          80           5

【问题讨论】:

  • 您可以将该图像重新发布为文本吗?它更容易阅读
  • 如果我写了一个非常好的但很长的解决方案查询,截取了它的屏幕截图,并添加了该图像作为答案,你会为转录工作而烦恼吗? 请不要使用数据图像,将一些数据粘贴到问题中并使用工具栏中的{} 按钮对其进行格式化。
  • 4 列名称是什么?我看到 3,不包括采取和离开。
  • 抱歉,我正在板上处理它以更好地理解它。列名是 Acc no、group、max、column4。提供这些。我需要提出“采取”和“左”列中提到的计算
  • 能否请您也发布预期结果,以便相应地准备查询。

标签: sql sql-server common-table-expression lag


【解决方案1】:

您可以使用OUTER APPLY 来实现,如下所示

DECLARE @table AS TABLE(acc_no INT, [group] CHAR(1), [maxgroup] INT, amount INT)

INSERT INTO @table VALUES
(101, 'A', 70, 0),
(101, 'B', 70, 50),
(101, 'C', 70, 0),
(101, 'D', 70, 20),
(102, 'A', 95, 30),
(102, 'B', 95, 0),
(102, 'C', 95, 5),
(102, 'D', 95, 10),
(103, 'A', 80, 40),
(103, 'B', 80,15),
(103, 'C', 80, 10),
(103, 'D', 80, 5)


SELECT t.acc_no, 
    t.[group],
    t.maxgroup,
    CASE WHEN t1.assigned = 0 THEN NULL ELSE t.amount END AS taken, 
    CASE WHEN t1.assigned = 0 THEN NULL ELSE (t.maxgroup - t1.assigned) END [left]
FROM @table t
OUTER APPLY(SELECT SUM([amount]) AS assigned 
            FROM @table t1 WHERE t1.acc_no = t.acc_no AND t1.[group] <= t.[group]) t1

输出:

    acc_no  group   maxgroup    taken   left
    101     A       70          NULL    NULL
    101     B       70          50      20
    101     C       70          0       20
    101     D       70          20      0
    102     A       95          30      65
    102     B       95          0       65
    102     C       95          5       60
    102     D       95          10      50
    103     A       80          40      40
    103     B       80          15      25
    103     C       80          10      15
    103     D       80          5       10

【讨论】:

  • 效果很好,我试图了解外部应用连接中实际发生的情况。由于 group 列是字符串或 varchar,t1.group
  • 实际上,如果你能解释一下你在这里应用的逻辑,那就太好了......谢谢一堆,我花了一整天的时间试图用复杂的逻辑来解决这个问题,你的方法看起来很简单并且容易。
  • 嗨,这一切看起来都不错,但是如果表格有类似这些的值 INSERT INTO @Table VALUES (104, 'A', 10, 0), (104, 'B', 10, 37), (104, 'C', 10, 0), (104, 'D', 10, 0) 它的排名第 37 位,应该是 10,因为 10 是可以给该组的最大值。
  • 解决了,非常感谢你让我继续这件事。感谢您的帮助。
  • 也感谢您为自己找到上述问题的解决方案所做的努力,实际上我很忙,所以无法帮助您。很抱歉,非常感谢您的赞赏。
【解决方案2】:

max(MaxGroup) over (partition by Accountno) 这将获得每个 Accountno 的 MaxGroup 值

sum(Amount) over (partition by Accountno order by GroupName) 这将给出累计总数Amount

-- create the sample table
DECLARE @sample AS TABLE
(
    Accountno   int,
    GroupName   char,
    MaxGroup    int,
    Amount      int
)

-- insert some sample data
INSERT INTO @sample VALUES
(101, 'A', 70,  0), 
(101, 'B', 70, 50), 
(101, 'C', 70,  0), 
(101, 'D', 70, 20),

(102, 'A', 95, 30), 
(102, 'B', 95,  0), 
(102, 'C', 95,  5), 
(102, 'D', 95, 10),

(103, 'A', 80, 40), 
(103, 'B', 80, 15), 
(103, 'C', 80, 10), 
(103, 'D', 80,  5)

-- the query
select  *, 
        [left]  = max(MaxGroup) over (partition by Accountno)
                - sum(Amount) over (partition by Accountno order by GroupName)
from    @sample s
order by Accountno, GroupName

不太明白您需要的倒数第二列taken 的逻辑是什么。在我看来,它与Amount 列相同

demo

【讨论】:

  • 非常感谢您在这方面的帮助。我想我已经解决了,但是取列基本上是可以使用第 3 列-第 4 列的值,但是当第 4 列大于第 3 列时,将使用第 3 列。
猜你喜欢
  • 2022-09-25
  • 2022-10-07
  • 2013-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多