总结查询结果的不同元素

时间:2014-09-29 13:25:48

标签: sql tsql

我有三个代表树结构的表。 #A中的每一行都是#B中零行或多行的祖先。同样,#B中的每一行都是#C中零行或多行的祖先。表#B包含一列value。我需要为属于输入祖先的value中的所有行找到#B的总和。

例如,请考虑以下表格内容:

CREATE TABLE #A (id varchar(10));
CREATE TABLE #B (id varchar(10), value int);
CREATE TABLE #C (id varchar(10), a_id varchar(10), b_id varchar(10));

INSERT INTO #A(id) VALUES ('A1'), ('A2');
INSERT INTO #B(id, value) VALUES('B1', 41), ('B2', 43), ('B3', 47);
INSERT INTO #C(id, a_id, b_id) VALUES('C1', 'A1', 'B1'), ('C2', 'A1', 'B1'),
                                     ('C3', 'A1', 'B2'), ('C4', 'A2', 'B3');

以上内容代表以下结构:

A1
|--- B1 (41)
|    |-------- C1
|    |-------- C2
|
|--- B2 (43)
     |-------- C3
A2
|--- B3 (47)
     |-------- C4

父子关系是奇怪的定义。表#B没有自己的列,表明表#A中的哪一行是其祖先。应从表#C评估所有映射。表a_id中的列b_id#C分别指定表#A#B中的祖父表和父行。如果Z中的#Ca_idXb_idY,则X为祖先Y YZ的祖先是#C的祖先。 A1中不存在冲突的映射。

问题陈述:对于给定的ID value,请查找#B中父级为A1的所有行的列A1的总和。这里有两个B1的孩子,41的值为B243的值为84,因此我们希望答案为SELECT SUM(#B.value) FROM #B INNER JOIN #C ON #B.id = #C.b_id INNER JOIN #A ON #C.a_id = #A.id WHERE #A.id = 'A1' 。< / p>

如果我做以下的事情:

125

我得到41 + 41 + 43,即84而不是#A,因为B1 -> C1中的两行都有映射#B。我可以在下面查询以获取与41中的不同行相关联的值,即43SELECT MAX(#B.value) FROM #B INNER JOIN #C ON #B.id = #C.b_id INNER JOIN #A ON #C.a_id = #A.id WHERE #A.id = 'A1' GROUP BY #B.id; ,但现在我不知道如何对结果值求和。我可以在不创建临时表的情况下获得预期结果吗?

{{1}}

我不是SQL专家,所以可能有一个非常简单的解决方案。

3 个答案:

答案 0 :(得分:1)

你可以这样做:

SELECT SUM(#B.value) 
FROM #B
WHERE EXISTS
(
    SELECT NULL FROM #C 
    INNER JOIN #A ON #C.a_id = #A.id
    WHERE #B.id = #C.b_id
    AND #A.id = 'A1'
)

然后,您只会总结其他表中存在的#B

结果将是:84

答案 1 :(得分:1)

这里你不需要表#A,因为ID在表#C和表#B中的值。这就是你所需要的一切。无需加入。只需从#C中选择所需的ID,然后使用它们从#B中选择。

select sum(value)
from #B
where id in
(
  select b_id
  from #C
  where a_id = 'A1'
);

答案 2 :(得分:0)

略有不同的方法。

SELECT SUM(#B.value) FROM #B
INNER JOIN (
  SELECT DISTINCT a_id, b_id FROM #C
  ) temp
ON
temp.b_id=#B.ID
WHERE temp.a_id='A1';

这样做的好处是,您可以将WHERE temp.a_id='A1'更改为GROUP BY temp.a