1

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

4

2 回答 2

9

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

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

然后您只需表连接在一起,GROUP BY现有表中的键和新表中的值ORDER BYAVG()SUM()GROUP_CONCAT()如果需要,您甚至可以使用 MySQL 的函数回收逗号分隔的列表:

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
于 2012-06-28T21:41:01.263 回答
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');

可以创建一个函数来返回“内爆数组”字符串中值的平均值。举个例子:

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

于 2012-06-28T23:10:55.170 回答