所以我在一个 mysql 表中有一个内爆数组,它基本上只是一个数字序列(例如 1、5、3、1、4、5),我想知道是否可以按平均值排序它们(甚至表中数字集的总和(如果可能的话)
问问题
221 次
2 回答
9
不要将数字存储在分隔字符串中,而是利用 MySQL 的关系功能并规范化数据:将数字(key, value)
成对存储在单独的表中,该表将外键(即现有表的外键)与列表中的单个数字相关联. 如果顺序很重要,请添加一列以指示该数字在列表中的位置。
CREATE TABLE `newtable` (
`key` INT,
`value` INT,
FOREIGN KEY (`key`) REFERENCES `existingtable` (`key`)
)
然后您只需将表连接在一起,GROUP BY
现有表中的键和新表中的值ORDER BY
的AVG()
或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 回答