汇总 where 子句中未选择的行

Posted

技术标签:

【中文标题】汇总 where 子句中未选择的行【英文标题】:summing up rows which are not selected in where clause 【发布时间】:2011-12-14 06:13:39 【问题描述】:

表格中的样本数据有 4 列:

1st row           A1    B1  C1  D1

2nd row           A1    B2  C2  D2

3rd row           A1    B3  C3  D3

4th row           A2    B1  C4  D4

5th row           A2    B4  C5  D5

6th row           A3    B1  C6  D6

我想*选择所有列*满足条件COL-B = B1的行 此外,我想要COL-D 的每个选定值的总和 COL-A

输出数据

1st row           A1    B1  C1  D1+D2+D3

2nd row           A2    B1  C4  D4+D5

3rd row           A3    B1  C6  D6

我无法弄清楚如何总结未在 where 子句中选择的行。请帮忙

【问题讨论】:

如果没有被选中,则不能相加 对不起,我是 sql 的菜鸟,但有没有办法通过两次加入同一个表来完成。忘了说 COL-A 和 COL-B 是主键 可能我没看懂问题,请忽略我的评论。 【参考方案1】:

以下两个之一应该可以工作:

SELECT A,B,C,(select SUM(D) from Table t2 where t2.A = t.A)
FROM Table t
WHERE t.B = 'B2'

或:

SELECT t.A,t.B,t.C,t2.D
FROM Table t
   inner join
       (select A,SUM(D) as D from Table) t2
      on
          t.A = t2.A
WHERE
    t.B = 'B2'

哪一个表现更好通常取决于表中总共有多少行,有多少行有B='B2',以及存在多少相关行(具有匹配的A值)。


或者,另一个:

SELECT A,MAX(CASE WHEN B='B2' THEN B END) as B,MAX(CASE WHEN B='B2' THEN C END) as C,SUM(D) as D
FROM Table
GROUP BY A
HAVING MAX(CASE WHEN B='B2' THEN B END) = 'B2'

这可能更有效(应该只导致一次表扫描 - 这里我假设表中的大多数行都应该在结果集中结束)

【讨论】:

非常感谢.. 这是最有用的.. 我会选择第一个,因为获取的行数通常比表中的总行数要小得多【参考方案2】:

如果你想在单个查询中求和和过滤条件,你需要使用子查询和分组,如下所示:

DECLARE @Table TABLE (Col1 VARCHAR(10), Col2 VARCHAR(10), Col3 VARCHAR(10), Col4 INT)

INSERT INTO @Table VALUES ('A1','B1','C1',1) 
INSERT INTO @Table VALUES ('A1','B2','C2',1)
INSERT INTO @Table VALUES ('A1','B3','C3',1)
INSERT INTO @Table VALUES ('A2','B1','C4',1)
INSERT INTO @Table VALUES ('A2','B4','C5',1)
INSERT INTO @Table VALUES ('A3','B1','C6',1)

SELECT  Col1, 
        (SELECT TOP 1 Col2 FROM @Table WHERE Col1 = MainTable.Col1) Col2,
        (SELECT TOP 1 Col3 FROM @Table WHERE Col1 = MainTable.Col1) Col3,
        SUM(Col4) AS Total 
FROM @Table MainTable
GROUP BY Col1

但在这里,您对 B1 的过滤条件不会满足所有情况。这只是您提到的输出。如果没有任何记录,例如 Col1=A4,那么它将获取 col2 中的任何值,例如 record =>> 'A4','B2','C6',1,它将返回 B2。

更新:参考。来自 Damien_The_Unbeliever 的帖子

对于 A4 案例,我认为您需要这样做:

SELECT  Col1,
        Col2,
        Col3,
        (SELECT SUM(Col4) FROM @Table t2 WHERE t2.Col1 = t.Col1) 
FROM @Table t 
WHERE t.Col2 = 'B1' 

【讨论】:

谢谢,但我会有一行“A4”,可能没有“B1”。这行不通:(【参考方案3】:

如果我用 SQL 解决这个问题,我会首先按列 A 分组,然后找到列 D 的总和。

此查询将使用内部查询,并对B='B1' 进行过滤。

select inn.A,inn.sum_d, Tb.B 
from (
    //inner query
    select A, sum(D) sum_d 
    from <table> Ta 
    group by A
) inn,
<table> Tb
where 
//join inner query output to table Tb.w here Ta and Tb are same table with 2 different alias name.
inn.A=Tb.A
and Tb.B= 'B1'

这个伪代码应该会给你想要的结果。

这可能不是一个理想的查询。但这是您正在寻找的基本逻辑。

【讨论】:

SELECT B.COL-A,INN.SUM_D FROM SELECT COL-A, SUM(COL-D) SUM_D FROM TABLE TA GROUP BY COL-A INN, TABLE B WHERE B.COL- A = INN.COL-A AND B.COL-B = 'B1' .. 我用过这个,但我得到 SQLCODE -104 说 '' 是非法的..我在 IBM SPUFI 上运行它,因为我需要这个COBOL DB2程序..是这个原因..我之前从未见过使用FROM子句中的查询 哎呀大括号是问题所在。你应该使用普通的支架。我会更正语法

以上是关于汇总 where 子句中未选择的行的主要内容,如果未能解决你的问题,请参考以下文章

选择行的间隔,包括一些带有 where 和 order 子句的行

SQL - 如何在have子句中对结果进行分组和筛选后,如何汇总列?

分组数据

分组数据

Oracle [过程] - Sum 函数忽略 WHERE 子句

使用多个 WHERE 子句和 GROUP BY 销售人员访问 SQL、聚合总和