我有一个包含几千行的表:从中我需要为列WTE
中的每个值提取列band
的总计,包括总计为0的那些。我也是需要每个总数都在自己的列中,以便我可以轻松更新汇总表。
我目前的代码返回相关行的值:
SELECT
IF(band="E",WTE,0) AS `Band6_WTE`
FROM `orthoptists` AS o
LEFT JOIN `instances` AS i
ON o.instance_FK = i.id
WHERE i.region = 14
但是当我添加SUM()时,返回是不正确的(零,当它应该是几千):
SELECT
IF(band="E",SUM(WTE),0) AS `Band6_WTE`
FROM `orthoptists` AS o
LEFT JOIN `instances` AS i
ON o.instance_FK = i.id
WHERE i.region = 14
我查看了http://en.wikibooks.org/wiki/MySQL/Pivot_table,但我不明白应该如何将这种方法应用于我的问题。
我该怎么办?
答案 0 :(得分:2)
你必须总结如果:
SELECT
SUM(IF(band="E",WTE,0)) AS `Band6_WTE`
FROM `orthoptists` AS o
LEFT JOIN `instances` AS i
ON o.instance_FK = i.id
WHERE i.region = 14
答案 1 :(得分:2)
在这种特殊情况下,使用WHERE
会不会更容易?
SELECT SUM(WTE) AS `Band6_WTE`
FROM `orthoptists` AS o
LEFT JOIN `instances` AS i
ON o.instance_FK = i.id
WHERE i.region = 14
AND band = "E"
对于一般情况,您可以使用GROUP BY
,因为您说您需要每个频段的结果(列频段中的每个值):
SELECT band, SUM(WTE) AS `WTE`
FROM `orthoptists` AS o
LEFT JOIN `instances` AS i
ON o.instance_FK = i.id
WHERE i.region = 14
GROUP BY band
这将给出NULL或0,如果您愿意,可以使用IFNULL
将NULL转换为0:
IFNULL(SUM(WTE), 0)
编辑:正如您在评论中指出的那样,您需要为不同的乐队而不是多行创建多个列。一般来说,你不应该从SQL那里做到这一点(使用第二个查询并从代码中执行数据透视操作),但有一些例外情况,在SQL之外这样做要复杂得多,所以这就是你如何做到的:
SELECT
(SELECT SUM(WTE)
FROM `orthoptists` AS o
LEFT JOIN `instances` AS i
ON o.instance_FK = i.id
WHERE i.region = 14
AND band = "E") AS `Band6_WTE`,
(SELECT SUM(WTE)
FROM `orthoptists` AS o
LEFT JOIN `instances` AS i
ON o.instance_FK = i.id
WHERE i.region = 14
AND band = "F") AS `Band7_WTE`,
(SELECT SUM(WTE)
FROM `orthoptists` AS o
LEFT JOIN `instances` AS i
ON o.instance_FK = i.id
WHERE i.region = 14
AND band = "G") AS `Band8_WTE`
准确的语法可能需要稍微调整一些(某些数据库要求每个SELECT
包含一个FROM
子句,有些可能需要为子选择中的每个列命名,我不认为MySQL确实如此,但我现在无法检查),但无论如何都应该适用该原则。
答案 2 :(得分:1)
Noody解释了为什么您的原始查询会给您错误的结果。
原始查询在SELECT
子句中具有聚合函数。这告诉MySQL这是一个聚合。没有GROUP BY
子句,因此它返回一行,将所有行视为一个组。
现在,在这种情况下band
会发生什么?在SQL标准或SQL的任何其他方言中,原始查询将返回错误,表示band
之类的内容未汇总。
MySQL有一个名为Hidden Columns的(mis)功能,允许使用这种语法。它需要来自所有行的随机值band
才能进行比较。该值可能具有值“E”,在这种情况下,返回所有WTE的总和。或者,它可能有另一个值,在这种情况下返回0。
通常,您应该避免使用隐藏列。当您有聚合查询时,SELECT
语句中的任何“裸”列也应该在GROUP BY
子句中。