Sql 对查询结果的不同元素求和
我有以下三个代表树结构的表。A中的每一行都是B中零行或多行的祖先。同样,B中的每一行都是C中零行或多行的祖先。表B包含一个列值。我需要找到B中属于输入祖先的所有行的值之和Sql 对查询结果的不同元素求和,sql,tsql,Sql,Tsql,我有以下三个代表树结构的表。A中的每一行都是B中零行或多行的祖先。同样,B中的每一行都是C中零行或多行的祖先。表B包含一个列值。我需要找到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)); I
例如,考虑以下表的内容:
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进行计算。表C中的a_id列和b_id列分别指定表a和b中的祖父母行和父行。如果C中有一行Z,其中a_id是X,b_id是Y,那么X是Y的祖先,Y是Z的祖先。C中不会有冲突的映射
问题陈述:对于给定的id A1,查找B中父级为A1的所有行的列值之和。这里有两个A1的子项,B1的值为41,B2的值为43,所以我们希望答案是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'
我得到125,即41+41+43,而不是84,因为A中的两行具有映射B1->C1。我可以写下面的查询来获得与B中不同行关联的值,即41和43,但现在我不知道如何对结果值求和。我是否可以在不创建临时表的情况下获得预期结果
SELECT 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;
我不是SQL专家,因此可能有一个非常简单的解决方案。您可以这样做:
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这里不需要表A,因为ID在表C中,值在表B中。这就是您所需要的。也不需要加入。只需从C中选择所需的ID,然后使用它们从B中选择
select sum(value)
from #B
where id in
(
select b_id
from #C
where a_id = 'A1'
);
略为不同的方法
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这是最简单的解决方案。正如你所说,不需要表A。我还要记住一点:当我们需要删除重复项时,内部连接不能替换WHERE-IN子句。