SQL中从另一个表中的特定点开始的求和值
我有一个表,列出了索引/顺序、名称和值。例如,它看起来像这样:SQL中从另一个表中的特定点开始的求和值,sql,sql-server,database,sum,nested-queries,Sql,Sql Server,Database,Sum,Nested Queries,我有一个表,列出了索引/顺序、名称和值。例如,它看起来像这样: TABLE1: ID | NAME | VALUE 1 | A | 2 2 | B | 5 3 | C | 2 4 | D | 7 5 | E | 0 TABLE2: NAME D B A 现在,我有另一个表,它有一个随机的名字列表。它只显示A、B、C、D或E。根据名称,我想计算得到E所需的所有值的总和。这有意义吗 例如,如果我的表如下所示: TABLE1: ID | NAME | VAL
TABLE1:
ID | NAME | VALUE
1 | A | 2
2 | B | 5
3 | C | 2
4 | D | 7
5 | E | 0
TABLE2:
NAME
D
B
A
现在,我有另一个表,它有一个随机的名字列表。它只显示A、B、C、D或E。根据名称,我想计算得到E所需的所有值的总和。这有意义吗
例如,如果我的表如下所示:
TABLE1:
ID | NAME | VALUE
1 | A | 2
2 | B | 5
3 | C | 2
4 | D | 7
5 | E | 0
TABLE2:
NAME
D
B
A
我想在NAME旁边再加一列,显示总数。所以D有7,因为下一个事件是E。B必须是5,2和7的和,因为B是5,C是2,D是7。A的和是2,5,3,7,依此类推
希望这很容易理解
实际上,除了连接两个表并获取名称的当前值之外,我没有什么其他的东西。但我不知道如何增加等等,并不断增加
SELECT T2.NAME, T1.VALUE
FROM Table1 T1
LEFT JOIN Table2 T2 ON T1.NAME = T2.NAME
这样做可能吗?还是我在浪费时间?我是否应该参考实际代码来执行此操作?或者我应该做一个函数
我不知道从哪里开始,我希望有人能帮助我
提前谢谢你 正如gregory所建议的,您可以使用一个简单的窗口函数来实现这一点,该函数(在本例中)将根据
ID
值汇总当前行之后的所有行。显然,有许多不同的方法可以对数据进行切片,不过我将让您自己去探索:)
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
这将输出:
+----+------+-----+----+
| ID | Name | Val | s |
+----+------+-----+----+
| 1 | A | 2 | 16 |
| 2 | B | 5 | 14 |
| 3 | C | 2 | 9 |
| 4 | D | 7 | 7 |
| 5 | E | 0 | 0 |
+----+------+-----+----+
查询分为两部分;这在一开始很难看到,所以我将逐步完成每一步 步骤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 |
+ ---- + ------ +
听起来你在寻找一个连续的总数;这是一个普通的窗口功能:看这个:我很难理解这一点。。那么,对于给定的第二个查询,#tab1是第一个查询中生成的表吗?因为我尝试了给出的第二个查询,它只给出了与表1相同的结果。很抱歉你能再解释一下吗?很抱歉。我在编写代码时使用临时表,这就是命名不同的原因。我的表1是你的表1,我的表2是你的表2。我会用这些变化来更新我的答案。哦,这一行做得很好,只需要多加一行。我肯定必须更彻底地研究这个窗口函数,但这正是我所要寻找的。@chakolatemilk有几种不同的方法可以使用
over
cluase,特别是使用分区来分组数据以提供聚合。它们是SQL的奇妙补充,可以节省大量的数据争用。