したがって、基本的には一連の数字(例:1,5,3,1,4,5)であるmysqlテーブルに内破された配列があり、それらを平均(または可能な場合は合計)テーブル内の数値のセット
2 に答える
数値を区切られた文字列に格納する代わりに、MySQL のリレーショナル機能を利用してデータを正規化します。(key, value)
外部キー (つまり、既存のテーブルのキー) をリスト内の単一の数値に関連付ける別のテーブルに数値をペアとして格納します。 . 順序が重要な場合は、リスト内の番号の位置を示す追加の列を含めます。
CREATE TABLE `newtable` (
`key` INT,
`value` INT,
FOREIGN KEY (`key`) REFERENCES `existingtable` (`key`)
)
次に、テーブルを結合するだけで済みGROUP BY
ます。既存のテーブルのキーと、新しいテーブルの値ORDER BY
のAVG()
orです。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
他の人が述べたように、テーブルがどのように見えるか、またはテーブル内のデータがどのように見えるかは明確ではありません。「崩壊した配列」がどのように見えるかは、まったく明確ではありません。これは、例が探している答えを得るのに本当に役立つ場所です。
しかし、ここでは「最悪の場合」に進み、平均したい値を含む文字列があると仮定します。このような:
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