Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 对查询结果的不同元素求和_Sql_Tsql - Fatal编程技术网

Sql 对查询结果的不同元素求和

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

我有以下三个代表树结构的表。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));

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子句。