我有三个代表树结构的表。 #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
中的#C
行a_id
为X
且b_id
为Y
,则X
为祖先Y
Y
和Z
的祖先是#C
的祖先。 A1
中不存在冲突的映射。
问题陈述:对于给定的ID value
,请查找#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'
。< / p>
如果我做以下的事情:
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;
,但现在我不知道如何对结果值求和。我可以在不创建临时表的情况下获得预期结果吗?
{{1}}
我不是SQL专家,所以可能有一个非常简单的解决方案。
答案 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