我已经阅读了类似问题的答案,并根据这些答案解决了我的问题。但是(我的)解决方案相当复杂,它包括两步视图,一个带左连接的附加表。我想知道下面的问题是否有更简单,更优雅的解决方案作为例证。表格Test
包含列B
,需要根据列Marker
的值为4或更高的条件进行汇总。表TestResult
是查询的所需输出。正如我所说,我确实有一个尴尬,复杂的解决方案,但我很好奇是否有一个简单,优雅的方法?
mysql> select * FROM Test;
+----+------+------+--------+
| ID | A | B | Marker |
+----+------+------+--------+
| 1 | 11 | 2 | 4 |
| 2 | 11 | 1 | 5 |
| 3 | 14 | 4 | 4 |
| 4 | 11 | 2 | 1 |
| 5 | 12 | 2 | 2 |
| 6 | 13 | 2 | 3 |
| 7 | 14 | 2 | 2 |
+----+------+------+--------+
7 rows in set (0.00 sec)
mysql> select * FROM TestResult;
+----+------+
| A | SumB |
+----+------+
| 11 | 3 |
| 12 | 0 |
| 13 | 0 |
| 14 | 4 |
+----+------+
4 rows in set (0.00 sec)
答案 0 :(得分:1)
编辑:我最初忽略了问题的“或结束”部分;让我认为需要一个不同的(更难以达到的)答案。我已经纠正了这个问题,但是由于有人显然觉得它很有帮助,所以留下了更难解答的解决方案。
使用LEFT JOIN可确保您从Test获得所有A值,subselect为您提供满足条件的行的A值的指示。
SELECT A, IF(t1.A IS NULL, 0, SUM(B)) AS sumB
FROM Test AS t0
LEFT JOIN (SELECT DISTINCT A FROM Test WHERE Marker >= 4) AS t1
ON t0.A = t1.A
GROUP BY A;
或者,这是最简洁的;但可能不太可靠甚至通过某些类型的连接被拒绝。
SELECT A, IF(SUM(IF(Marker>=4,1,0))>0, SUM(B),0) AS sumB
FROM Test
GROUP BY A;
答案 1 :(得分:1)
可以使用group by
和case
:
select A, sum(case when marker >= 4 then B else 0 end)
from Test
group by A;
查看此SQL Fiddle
答案 2 :(得分:0)
我这样做。从这开始:
SELECT t.A
FROM Test t
GROUP BY t.A
这很容易。
对于第二列,我们需要表达式的SUM ...
SELECT t.A
, SUM(expr) AS SumB
FROM Test t
GROUP BY t.A
诀窍是使用一个表达式来执行条件测试,该表达式测试确定是否应该返回B列的值。例如,在MySQL特定语法中,类似于:
IF(t.Marker >= 4, t.B, 0)
或者,更符合ANSI标准的等价物:
CASE WHEN t.Marker >= 4 THEN t.B ELSE 0 END
把所有这些放在一起......
SELECT t.A
, SUM(IF(t.Marker >= 4, t.B, 0)) AS SumB
FROM Test t
GROUP BY t.A
修改强>
如果在Test
+----+------+------+--------+
| ID | A | B | Marker |
+----+------+------+--------+
| 1 | 11 | 2 | 4 |
| 2 | 11 | 1 | 5 |
| 17 | 11 | 4 | 1 |
我质疑标记值为1(不大于或等于4)的行是否应将B
的值包括在SUM中?
上面的查询,您获得的SumB值为3.只是前两行的值将包含在SUM中。
如果你需要为SumB返回值7(包括第三行),那么你需要一个不同的查询模式。