汇总 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子句中对结果进行分组和筛选后,如何汇总列?