2012-01-18 148 views
5

我想寫一個函數來計算MySQL中的簡單修剪平均值計算。該函數將(顯然)是一個聚合函數。我是新手,在MySQL中編寫函數等,所以可以做一些幫助。MySQL中的修剪平均值計算

微調平均值的算法如下(僞代碼):

CREATE AGGREGATE FUNCTION trimmed_mean(elements DOUBLE[], trim_size INTEGER) 
RETURNS DOUBLE 
BEGIN 
    -- determine number of elements 
    -- ensure that number of elements is greater than 2 * trim_size else return error 
    -- order elements in ASC order 
    -- chop off smallest trim_size elements and largest trim_size elements 
    -- calculate arithmetic average of the remaining elements 
    -- return arithmetic average 
END 

任何人都可以用如何正確以上的寫入功能,與MySQL的使用幫助?

+2

是否有具體的原因,你想做這個功能,而不是作爲一個查詢?此外,由於您使用標準SQL,因此您首選回答上一個問題,您是否需要能夠跨越多個不同的RDBMS(即,不僅僅是MySQL)使用它? – 2012-01-18 10:34:45

+0

@MarkBannister我打算使用PG(我最喜歡的數據庫!),但是我不得不跳過太多的環節讓PG使用PHP(重新編譯PHP [或類似的瘋狂請求]等),所以我選擇了mySQL我已經在使用PHP。我想將它作爲函數的原因是我想在查詢中返回一個修剪的平均值作爲列。我想(如果我有一個SQL解決方案),我可以將一些SQL拼湊在一起,將修剪後的平均值作爲列「粘貼」到返回的數據集中。 – 2012-01-18 11:17:00

+0

@MarkBannister:簡短的回答你的問題。 ANSI SQL版本將是理想的。但是由於我恰好在使用mySQL,因此如果我__擁有以db爲中心的特性,那麼MySQL風格的SQL將優先。 – 2012-01-18 11:24:18

回答

1

這是不小的任務,你需要把它寫在C/C++ ...


內的MySQL本身的選項,就是寫一個視圖或標量函數它彙總數據的方式,但是來自特定的表格。這顯然將功能限制在單個源表中,這可能並不理想。

解決的辦法可能是有專門爲這一功能表...

  • 啓動事務
  • 清檯
  • 插入您的樣本數據
  • 查詢查看/功能

(或類似的東西)

這排除了GROUP BY變體,除非您爲特定分組模式使用動態sql或傳遞函數參數。

這一切都不太理想,對不起。

+0

我不介意C/C++路由最後的手段) - 但我寧願不,因爲我不想花費數小時來熟悉mySQL內部數據類型等。如果以C/C++編寫的集合有'hello world'示例,那麼將是一個非常好的起點(減少學習曲線),因爲我想做的事情是相對平凡的(算法部分)。 – 2012-01-18 11:20:41

+0

在來自Dems的鏈接中:*「MySQL源代碼分發包含一個定義5個新函數的文件sql/udf_example.c」* – 2012-01-18 11:31:44

1

看一看這個例子中(用於MySQL的) -

創建測試表:

CREATE TABLE test_table (
    id INT(11) NOT NULL AUTO_INCREMENT, 
    value INT(11) DEFAULT NULL, 
    PRIMARY KEY (id) 
); 

INSERT INTO test_table(value) VALUES 
    (10), (2), (3), (5), (4), (7), (1), (9), (3), (5), (9); 

讓我們來計算平均價值(編輯變種):

SET @trim_size = 3; 

SELECT AVG(value) avg FROM (
    SELECT value, @pos:[email protected] + 1 pos FROM (SELECT * FROM test_table ORDER BY value) t1, (SELECT @pos:=0) t2 
) t 
WHERE pos > @trim_size AND pos <= @pos - @trim_size; 

+--------+ 
| avg | 
+--------+ 
| 4.8000 | 
+--------+ 
+0

當然它應該是4.8--修剪應該消除一個而不是兩個3s?即:(not(1 + 2 + 3)+ 3 + 4 + 5 + 5 + 7 + not(9 + 9 + 10))/ 5 – 2012-01-18 12:37:00

+0

@Mark Ba​​nnister你是對的。我錯過了ASC訂單中的點順序元素。它應該按'value'字段排序。我編輯了查詢。謝謝;-) – Devart 2012-01-18 15:02:57