2012-06-28 30 views
1

所以我有一個內部數組在一個MySQL表中基本上只是一個數字序列(例如1,5,3,1,4,5),我想知道如果有可能按表MYSQL:由一個數組的平均排序

+0

提供一些示例數據以及所需結果的示例。 –

+3

它們是否作爲CSV字符串存儲在VARCHAR中?因爲如果是這樣的話,你現在應該放棄--MySQL沒有字符串拆分功能,雖然創建UDF有很多勇於嘗試的方法,但是沒有一個能夠勝任這項工作,主要原因是MySQL也是如此本身不具有用於存儲結果的合適的矢量類型。您應該創建一個單獨的表格以便將其存儲爲一對多關係,然後它只是一個簡單的「GROUP BY」,平均值和總和都很容易。 – DaveRandom

回答

9

中的數字集的平均值(或者甚至總和,如果可能的話)對它們進行排序而不是將您的數字存儲在分隔字符串中,而是利用MySQL的關係功能並規範化數據:將您的號碼作爲(key, value)對存儲在單獨的表格中,該表格將外鍵(即現有表格的外鍵)與列表中的單個數字相關聯。如果訂單很重要,請在列表中添加一個附加列以指示該號碼的位置。

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

然後,你需要的表僅join在一起,GROUP BY關鍵在你現有的表和ORDER BYAVG()或在新表中的值的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

http://sqlfiddle.com/#!2/f0e13/1 - +1以獲得最佳答案(PS我更正了一個語法錯誤,因爲'values'是一個保留字) – DaveRandom

1

正如其他人所說,這不是清除表是什麼樣子,或者你在表中的數據的樣子。這完全不清楚「內爆陣列」是什麼樣子。這是一個EXAMPLE將真正幫助您獲得您正在尋找的答案的地方。

但讓我們來看看這裏的「最糟糕的情況」,並假設你有一個包含你想要平均值的字符串。像這樣:

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的字符串到數字的隱式轉換,所以空字符串或無效的數字將被轉換爲零,並且零計算將被添加並計算在計算平均值中。

A do_sum函數將幾乎相同,只是返回總數而不是總數除以計數。

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