SQL中的SUM值从另一个表中的特定点开始

问题描述:

我有一个列出索引/顺序,名称和值的表。例如,它看起来像这样:SQL中的SUM值从另一个表中的特定点开始

TABLE1: 
ID | NAME | VALUE 
1 | A | 2 
2 | B | 5 
3 | C | 2 
4 | D | 7 
5 | E | 0 

现在,我有了名的随机列表中的另一个表。它只会显示A,B,C,D或E.根据NAME的内容,我想计算所有值到E的值的总和。这是否有意义?

所以如果举例来说,我的表是这样的:

TABLE2: 
NAME 
D 
B 
A 

我接下来要名称会显示总和另一列。所以D会有7个,因为下一个事件是E.B必须是5,2和7的总和,因为B是5,C是2,D是7.A的和是2, 5,3,7等。

希望这很容易理解。

除了加入两张表并获取NAME的当前值之外,我其实没有太多东西。但我不知道如何增加等等,并继续增加?

SELECT T2.NAME, T1.VALUE 
FROM Table1 T1 
LEFT JOIN Table2 T2 ON T1.NAME = T2.NAME 

这样做甚至有可能吗?还是我在浪费时间?我应该引用实际的代码来做到这一点吗?或者我应该做一个功能?

我不确定从哪里开始,我希望有人能帮助我。

预先感谢您!

+1

听起来就像你正在寻找一个运行的总和;这是一个正常的窗口功能:看到这个:https://www.wagonhq.com/blog/running-totals-sql – gregory

正如格雷戈里建议,你可以用一个简单的窗函数,它(这种情况下)会后总结了所有的行和包括基于该ID值当前一个做到这一点。显然,有许多不同的方法,使你可以切片数据,但我会离开,你来探索:)


declare @t table(ID int,Name nvarchar(50),Val int); 
insert into @t values(1,'A',2),(2,'B',5),(3,'C',2),(4,'D',7),(5,'E',0); 

select ID  -- The desc makes the preceding work the right way. This is 
     ,Name -- essentially shorthand for "sum(Val) over (order by ID rows between current row and unbounded following)" 
     ,Val -- which is functionally the same, but a lot more typing... 
     ,sum(Val) over (order by ID desc rows unbounded preceding) as s 
from @t 
order by ID; 

将输出:

+----+------+-----+----+ 
| ID | Name | Val | s | 
+----+------+-----+----+ 
| 1 | A | 2 | 16 | 
| 2 | B | 5 | 14 | 
| 3 | C | 2 | 9 | 
| 4 | D | 7 | 7 | 
| 5 | E | 0 | 0 | 
+----+------+-----+----+ 
+0

哇,这个工作非常好,只需要一个额外的线。我肯定会更深入地研究这个窗口函数,但这正是我所期待的。 – chakolatemilk

+0

@chakolatemilk有几种不同的方法可以使用'over'cluase,特别是'partition'可以将数据分组以提供聚合。它们是SQL的绝妙增加,可以节省大量的数据纠缠。 – iamdave

CREATE TABLE #tempTable2(name VARCHAR(1)) 
INSERT INTO #tempTable2(name) 
VALUES('D') 
INSERT INTO #tempTable2(name) 
VALUES('B') 
INSERT INTO #tempTable2(name) 
VALUES('A') 


CREATE TABLE #tempTable(id INT, name VARCHAR(1), value INT) 
INSERT INTO #temptable(id,name,value) 
VALUES(1,'A',2) 
INSERT INTO #temptable(id,name,value) 
VALUES(2,'B',5) 
INSERT INTO #temptable(id,name,value) 
VALUES(3,'C',2) 
INSERT INTO #temptable(id,name,value) 
VALUES(4,'D',7) 
INSERT INTO #temptable(id,name,value) 
VALUES(5,'E',0) 



;WITH x AS 
(
    SELECT id, value, name, RunningTotal = value 
    FROM dbo.#temptable 
    WHERE id = (SELECT MAX(id) FROM #temptable) 

    UNION ALL 

    SELECT y.id, y.value, y.name, x.RunningTotal + y.value 
    FROM x 
     INNER JOIN dbo.#temptable AS y ON 
      y.id = x.id - 1 

) 
SELECT x.id, x.value, x.name, x.RunningTotal 
    FROM x 
    JOIN #tempTable2 t2 ON 
     x.name = t2.name 
    ORDER BY x.id 



DROP TABLE #tempTable 
DROP TABLE #tempTable2 

该查询分两部分,起初很难看到,所以我会走过每一步。

步骤1:获取轧制总和

加入表1到本身为比本身更大的任何字母:

select * 
    from table1 t1 
    inner join table1 t2 on t2.name >= t1.name 
    order by t1.name 

这将产生如下表

+ -- + ---- + ----- + -- + ---- + ----- + 
| id | name | value | id | name | value | 
+ -- + ---- + ----- + -- + ---- + ----- + 
| 1 | A | 2  | 1 | A | 2  | 
| 1 | A | 2  | 2 | B | 5  | 
| 1 | A | 2  | 3 | C | 2  | 
| 1 | A | 2  | 4 | D | 7  | 
| 1 | A | 2  | 5 | E | 0  | 
| 2 | B | 5  | 2 | B | 5  | 
| 2 | B | 5  | 3 | C | 2  | 
| 2 | B | 5  | 4 | D | 7  | 
| 2 | B | 5  | 5 | E | 0  | 
| 3 | C | 2  | 3 | C | 2  | 
| 3 | C | 2  | 4 | D | 7  | 
| 3 | C | 2  | 5 | E | 0  | 
| 4 | D | 7  | 4 | D | 7  | 
| 4 | D | 7  | 5 | E | 0  | 
| 5 | E | 0  | 5 | E | 0  | 
+ -- + ---- + ----- + -- + ---- + ----- + 

注意,如果我们按照t1的名字进行分组,我们可以通过将t2的值相加来得到滚动和。该查询

select t1.name, 
     SUM(t2.value) as SumToE 
    from table1 t1 
    inner join table1 t2 
     on t2.name >= t1.name 
    group by t1.name 

给我们的滚动资金,我们希望

+ ---- + ------ + 
| name | sumToE | 
+ ---- + ------ + 
| A | 16  | 
| B | 14  | 
| C | 9  | 
| D | 7  | 
| E | 0  | 
+ ---- + ------ + 

注:这相当于使用概括了一组窗口的功能,但它是非常容易直观地看到什么你正在通过这种连接技术。

第2步:加入滚动总和

现在,你必须为每个信这个滚动总和,您只需加入它参见表2你想

select t1.* 
    from table2 t2 
    inner join (
     select t1.name, 
       SUM(t2.value) as SumToE 
      from table1 t1 
      inner join table1 t2 
       on t2.name >= t1.name 
      group by t1.name 
    ) t1 on t1.name = t2.name 

结果的字母:

+ ---- + ------ + 
| name | sumToE | 
+ ---- + ------ + 
| A | 16  | 
| B | 14  | 
| D | 7  | 
+ ---- + ------ + 
+0

我有一个相当困难的时间跟随此..所以对于第二个查询给出,是#tab1在第一个查询中产生的表?因为我尝试了第二个查询,它只给了我与Table1本身相同的结果。抱歉!你能多解释一下吗? – chakolatemilk

+0

对不起。我在写代码时使用了临时表,所以这就是命名不同的原因。我的#tab1是你的Table1,我的#tab2是你的Table2。我将通过这些更改更新我的答案 – KindaTechy