我有以下数据表和数据:
mysql> describe school_data_sets_numeric_data;
+--------------+----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| data_set_nid | int(11) | NO | | NULL | |
| school_nid | int(11) | NO | | NULL | |
| year | int(11) | NO | | NULL | |
| description | varchar(255) | NO | | NULL | |
| value | decimal(18,12) | NO | | NULL | |
+--------------+----------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
+----+--------------+------------+------+-------------------+------------------+
| id | data_set_nid | school_nid | year | description | value |
+----+--------------+------------+------+-------------------+------------------+
| 54 | 19951 | 19944 | 2008 | Asian | 75.000000000000 |
| 51 | 19951 | 19944 | 2008 | White | 200.000000000000 |
| 52 | 19951 | 19944 | 2008 | African American | 100.000000000000 |
| 53 | 19951 | 19944 | 2008 | Hispanic | 50.000000000000 |
| 55 | 19951 | 19944 | 2008 | Native American | 9.000000000000 |
我想显示数据的平均值而不是原始数字。我想在raw sql中执行此操作。
示例:
+----+--------------+------------+------+-------------------+------------------+
| id | data_set_nid | school_nid | year | description | average |
+----+--------------+------------+------+-------------------+------------------+
| 54 | 19951 | 19944 | 2008 | Asian | 17.28% |
| 51 | 19951 | 19944 | 2008 | White | 46.06% |
| 52 | 19951 | 19944 | 2008 | African American | 23.04% |
| 53 | 19951 | 19944 | 2008 | Hispanic | 11.52% |
| 55 | 19951 | 19944 | 2008 | Native American | 2.07% |
最好的方法是什么?请记住,将有多个数据集和年份。
答案 0 :(得分:6)
执行此操作的一种方法是编写一个获取“总值”的查询,这将是您的平均值的分母。
SELECT SUM(value) AS total_value FROM school_data_sets_numeric_data
将该查询的结果与表格的每一行结合起来,这样就可以得到可用的值和总数,用于计算平均值。
SELECT v.id
, v.data_set_nid
, v.school_nid
, v.year
, v.description
-- , v.value
-- , t.total_value
, CONCAT(FORMAT(IF(t.total_value=0,0,(v.value*100.0)/t.total_value),2),'%')
AS `average`
FROM (SELECT SUM(value) AS total_value FROM school_data_sets_numeric_data) t
CROSS
JOIN school_data_sets_numeric_data v
关键字CROSS
是可选的,但它可以作为后来评论者的文档,并让他们知道我们打算创建一个笛卡尔积,并且我们故意遗漏(并且不会意外省略) JOIN的ON
子句。
返回“average”的表达式会在您显示时显示该值...四舍五入到带有尾随百分号的两位小数。
计算“平均值”很简单...... value / total_value * 100
。
(如果分子和说明者都是整数类型,请注意“整数”除法,在您的情况下不是问题,但我们通过乘以十进制文字确保分子是十进制,这确保我们有十进制类型值。)< / p>
表达式的其余部分涉及避免可能的“除以零”异常,四舍五入到小数点后两位,格式化两个固定小数位,并附加'%'。
如果你想要那些%符号排成一行,你可以用空格填充该字符串的左侧,达到特定长度,例如LPAD(expr,7,' ')
。 (实际上,我可能会在增加%'的CONCAT之前做到这一点,但这并不重要。)
如果您打算对子集进行平均,例如,对于特定年份和特定数据集,而不是整个返回集,那么我们将获得每个数据组的“小计”。
在这里,我们计算特定data_set_nid
和year
的平均值:
SELECT v.id
, v.data_set_nid
, v.school_nid
, v.year
, v.description
-- , v.value
-- , t.total_value
, CONCAT(FORMAT(IF(t.total_value=0,0,(v.value*100.0)/t.total_value),2),'%')
AS `average`
FROM (SELECT u.data_set_nid
, u.year
, SUM(u.value) AS total_value
FROM school_data_sets_numeric_data u
GROUP
BY u.data_set_nid
, u.year
) t
JOIN school_data_sets_numeric_data v
ON v.data_set_nid = t.data_set_nid
, v.year = t.year
答案 1 :(得分:2)
试试这个。
select @total:=sum(value) from school_data_sets_numeric_data;
select id, data_set_nid, school_nid, year, description,
concat(round((100*actor_id)/@total,2),"%") as percentage
from school_data_sets_numeric_data;
输入将是那样的
答案 2 :(得分:0)
尝试以下方法。在sqlfidlle上测试过。
select id, data_set_nid,school_nid, year, description, round(value/(select sum(value) from school_data_sets_numeric_data)*100,2) as average from school_data_sets_numeric_data