2012-01-18 57 views
5

Tôi muốn viết một hàm tính toán phép tính trung bình được cắt đơn giản trong MySQL. Hàm sẽ (rõ ràng) là hàm tổng hợp. Tôi mới để viết chức năng vv trong MySQL để có thể làm với một số trợ giúp.Tính toán trung bình được rút gọn trong MySQL

Thuật toán của giá trị trung bình tỉa sẽ như sau (giả):

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 

bất cứ ai có thể giúp với làm thế nào để viết các chức năng trên một cách chính xác, để sử dụng với MySQL?

+2

Có lý do cụ thể mà bạn muốn làm điều này như là một chức năng, chứ không phải là một truy vấn? Ngoài ra, nếu bạn thích câu trả lời cho câu hỏi trước bởi vì nó đã sử dụng SQL chuẩn, bạn sẽ cần phải có khả năng sử dụng nó trên nhiều RDBMS khác nhau (tức là không chỉ MySQL)? –

+0

@MarkBannister Tôi dự định làm việc với PG (db yêu thích của tôi!), Nhưng tôi phải nhảy qua quá nhiều vòng để có PG để làm việc với PHP (biên dịch lại PHP [hoặc yêu cầu tương tự điên rồ] vv), vì vậy tôi đã chọn mySQL Tôi đã làm việc với PHP. Lý do tôi muốn nó như là một chức năng là tôi muốn trả lại một trung bình cắt như một cột trong một truy vấn. Tôi giả sử (nếu tôi có một giải pháp SQL), tôi có thể hack cùng một số SQL để 'dán' các giá trị trung bình đã cắt thành cột vào tập dữ liệu trả về của tôi. –

+0

@MarkBannister: câu trả lời ngắn cho câu hỏi của bạn. Một phiên bản ANSI SQL sẽ là lý tưởng. Nhưng kể từ khi tôi tình cờ làm việc với mySQL, sau đó nếu tôi __have__ là db-centric, một SQL có hương vị MySQL sẽ được ưu tiên. –

Trả lời

1

Đó là nhiệm vụ không hề nhỏ, bạn cần phải viết nó trong c/C++ ...


Một tùy chọn trong MySQL chính nó, là để viết một cái nhìn hoặc vô hướng chức năng tổng hợp dữ liệu theo cách bạn muốn, nhưng từ một bảng cụ thể. Điều này rõ ràng hạn chế chức năng cho một bảng nguồn duy nhất, có thể không lý tưởng.

Một khoảng cách này có thể là để có một bảng dành riêng cho chức năng này ...

  • bắt đầu một giao dịch
  • rõ ràng bàn
  • chèn dữ liệu mẫu của bạn
  • truy vấn chế độ xem/chức năng

(Hoặc nội dung tương tự)

Điều này ngăn cản các biến thể GROUP BY, trừ khi bạn sử dụng tham số sql hoặc thông số động cho hàm của bạn cho các mẫu nhóm cụ thể.

Tất cả đều lý tưởng, xin lỗi.

+0

Tôi không ngại đi xuống tuyến đường C/C++ (như một phương sách cuối cùng) - nhưng tôi không muốn, đơn giản là vì tôi không muốn mất nhiều thời gian để tự làm quen với các kiểu dữ liệu nội bộ mySQL vv. Nếu có một ví dụ 'hello world' cho một tổng hợp được viết bằng C/C++, sẽ là một điểm khởi đầu rất tốt (trong việc giảm đường cong học tập), vì những gì tôi muốn làm, là tương đối tầm thường (phần thuật toán đó là). –

+0

Trong liên kết từ Dems: * "Phân phối nguồn MySQL bao gồm một tệp sql/udf_example.c xác định 5 hàm mới." * –

1

Hãy nhìn vào ví dụ này (đối với MySQL) -

Tạo bảng thử nghiệm:

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); 

Hãy tính giá trị trung bình (sửa biến):

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

Chắc chắn nó phải là 4,8 - phần cắt phải loại bỏ một chứ không phải cả 3? ví dụ: (không (1 + 2 + 3) + 3 + 4 + 5 + 5 + 7 + không (9 + 9 + 10))/5 –

+0

@Mark Bannister Bạn nói đúng. Tôi đã bỏ qua các yếu tố theo thứ tự điểm trong thứ tự ASC. Nó sẽ được sắp xếp theo trường 'value'. Tôi đã chỉnh sửa truy vấn. Cảm ơn;-) – Devart

Các vấn đề liên quan