SQL中的SUM值从另一个表

时间:2017-03-01 16:16:21

标签: 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

现在,我有另一个包含NAME随机列表的表。它只显示A,B,C,D或E.根据NAME的不同,我想计算到达E所需的所有值的总和。这有意义吗?

所以,例如,如果我的表看起来像这样:

TABLE2:
NAME
D
B
A

我希望NAME旁边的其他列显示总和。所以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

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

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

提前谢谢!

3 个答案:

答案 0 :(得分:2)

查询分为两部分;这一开始很难看,所以我会逐步完成每一步。

第1步:获得滚动金额

将table1连接到自身以获取任何大于其自身的字母:

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步:加入滚动总和

现在你已经为每个字母提供了这个滚动总和,你只需将它连接到table2即可得到你想要的字母

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      |
+ ---- + ------ +

答案 1 :(得分:1)

正如格雷戈里所建议的那样,你可以用一个简单的窗口函数来做到这一点,在这种情况下,它会根据var data = (IDictionary<string, object>)form; 值对当前行之后的所有行进行求和。显然,您可以通过多种不同的方式对数据进行切片,但我会将其留给您探讨:)

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;

答案 2 :(得分:0)

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