MYSQL:按数组的平均值排序

时间:2012-06-28 21:32:53

标签: php mysql arrays sum average

所以我在mysql表中有一个内爆数组,基本上只是一个数字序列(例如1,5,3,1,4,5),我想知道是否有可能按平均顺序排序(或者甚至是可能的总和)表中的数字组

2 个答案:

答案 0 :(得分:9)

不是将数字存储在分隔的字符串中,而是利用MySQL的关系功能并规范化数据:将数字存储为(key, value)对,并将其存储在与外键相关的单独表中(即现有表的外键) )到列表中的单个数字。如果订单很重要,请添加一个附加列以指示该列表中的编号位置。

CREATE TABLE `newtable` (
  `key`   INT,
  `value` INT,
  FOREIGN KEY (`key`) REFERENCES `existingtable` (`key`)
)

然后,您只需要join个表格,GROUP BY现有表格中的密钥以及ORDER BY AVG()SUM()个值新表;如果需要,您甚至可以使用MySQL的GROUP_CONCAT()函数回收逗号分隔列表:

SELECT   `existingtable`.*, GROUP_CONCAT(`newtable`.`value`) AS `values`
FROM     `existingtable` LEFT JOIN `newtable` USING (`key`)
GROUP BY `key`
ORDER BY AVG(`newtable`.`value`) -- or use SUM() if preferred

答案 1 :(得分:1)

正如其他人所提到的,目前还不清楚你的表是什么样的,或者表中的数据是什么样的。目前还不清楚“内爆阵列”是什么样的。这是一个例子可以帮助你找到你想要的答案。

但是,让我们选择“最坏情况”,并假设你有一个包含你想要平均值的字符串。像这样:

CREATE TABLE foo (str VARCHAR(1000));
INSERT INTO foo VALUES ('1,5,3,1,4,5');
INSERT INTO foo VALUES ('2.8,4.2');
INSERT INTO foo VALUES ('bar');
INSERT INTO foo VALUES (' 0, -2, 3');

可以创建一个函数,返回“imploded array”字符串中值的平均值。举个例子:

DELIMITER $$
CREATE FUNCTION `do_average`(p_str VARCHAR(2000))
RETURNS DOUBLE
BEGIN
  DECLARE c INT;
  DECLARE i INT;
  DECLARE s VARCHAR(2000);
  DECLARE v DOUBLE;
  SET c = 0;
  SET v = 0;
  SET s = CONCAT(p_str,',');
  SET i = INSTR(s,',');
  WHILE i > 0 DO
    SET v = v + SUBSTR(s,1,i);
    SET c = c + 1;
    SET s = SUBSTR(s,i+1,2000);
    SET i = INSTR(s,',');
  END WHILE;
  RETURN v / NULLIF(c,0);
END$$
DELIMITER ;

我们可以证明这一点:

SELECT f.str
     , do_average(f.str) AS davg
  FROM foo f
 ORDER BY do_average(f.str)

str                       davg  
-----------  -------------------
bar                            0
 0, -2, 3      0.333333333333333
1,5,3,1,4,5     3.16666666666667
2.8,4.2                      3.5

请注意,使用此函数,我们使用MySQL将字符串隐式转换为数字,因此空字符串或无效数字将转换为零,并且将在计算平均值时添加并计算零值

do_sum函数几乎相同,只返回总数而不是总数除以计数。

sqlfiddle示例http://sqlfiddle.com/#!2/4391b/2/0