2013-04-02 41 views

Trả lời

20

Giả sử trung vị là phần tử nằm giữa danh sách được sắp xếp.

SQLite (4 hoặc 3) không có bất kỳ built-in chức năng cho rằng, nhưng nó có thể làm điều này bằng tay:

SELECT x 
FROM MyTable 
ORDER BY x 
LIMIT 1 
OFFSET (SELECT COUNT(*) 
     FROM MyTable)/2 

Khi có một số chẵn các hồ sơ, nó phổ biến để xác định trung bình là mức trung bình của hai bản ghi giữa. Trong trường hợp này, tỷ lệ trung bình có thể được tính như thế này:

SELECT AVG(x) 
FROM (SELECT x 
     FROM MyTable 
     ORDER BY x 
     LIMIT 2 
     OFFSET (SELECT (COUNT(*) - 1)/2 
       FROM MyTable)) 

Kết hợp các số lẻ và chẵn trường hợp sau đó kết quả này:

SELECT AVG(x) 
FROM (SELECT x 
     FROM MyTable 
     ORDER BY x 
     LIMIT 2 - (SELECT COUNT(*) FROM MyTable) % 2 -- odd 1, even 2 
     OFFSET (SELECT (COUNT(*) - 1)/2 
       FROM MyTable)) 
+4

Đây là giải pháp tốt, nhưng có vẻ khó sử dụng nếu bạn muốn tính trung bình của kết quả "nhóm theo" thay vì toàn bộ bảng. Xem xét "chọn grp, min (val), trung bình (val), max (val) từ nhóm bảng bằng grp". –

+0

@Acer - Tôi thấy rằng bạn chính xác. Trong trường hợp này, tôi không có một giải pháp câu lệnh đơn giản, thanh lịch mà không có hỗ trợ cơ sở dữ liệu cho MEDIAN. Điều gì đến với tâm trí này là: 1) Tạo một bảng bằng cách sử dụng nhóm theo mệnh đề và SELECT INTO (gọi bảng này là "G"), ở dạng được sắp xếp và thêm cột AUTOINCREMENT (gọi là cột "i"). 2) Tạo truy vấn tính toán (tối đa (G.i) + phút (G.i))/2.0 cho mỗi nhóm (gọi cột này là 'x'). 3) Sử dụng bảng Pick, chọn các mục từ G trong đó ABS (G.i-Pick.x) <1. Nếu bạn lấy mức trung bình từ bảng cuối cùng đó, bạn sẽ có câu trả lời cho mỗi nhóm. Không đẹp. –

11

Có một gói mở rộng của hàm toán học khác nhau cho sqlite3. Nó bao gồm các chức năng nhóm như trung bình.

Sẽ có nhiều công việc làm việc này hơn là câu trả lời của CL, nhưng có thể đáng giá nếu bạn nghĩ bạn sẽ cần bất kỳ chức năng nào khác.

http://www.sqlite.org/contrib/download/extension-functions.c?get=25

(Here là hướng dẫn làm thế nào để biên dịch và phần mở rộng tải SQLite.)

Từ mô tả:

Provide mathematical and string extension functions for SQL queries using the loadable extensions mechanism. Math: acos, asin, atan, atn2, atan2, acosh, asinh, atanh, difference, degrees, radians, cos, sin, tan, cot, cosh, sinh, tanh, coth, exp, log, log10, power, sign, sqrt, square, ceil, floor, pi. String: replicate, charindex, leftstr, rightstr, ltrim, rtrim, trim, replace, reverse, proper, padl, padr, padc, strfilter. Aggregate: stdev, variance, mode, median, lower_quartile, upper_quartile.

CẬP NHẬT 2015/04/12: Khắc phục "biểu tượng không xác định: sinh "

Như đã được đề cập trong nhận xét, tiện ích mở rộng này có thể không hoạt động bình thường mặc dù biên dịch thành công.

Ví dụ: việc biên dịch có thể hoạt động và trên Linux, bạn có thể sao chép tệp .so thành /usr/local/lib. Nhưng .load /usr/local/lib/libsqlitefunctions từ vỏ sqlite3 sau đó có thể tạo ra lỗi này:

Error: /usr/local/lib/libsqlitefunctions.so: undefined symbol: sinh 

Biên soạn theo cách này dường như làm việc:

gcc -fPIC -shared extension-functions.c -o libsqlitefunctions.so -lm 

Và sao chép các tập tin .so để /usr/local/lib cho thấy không có lỗi tương tự:

sqlite> .load /usr/local/lib/libsqlitefunctions 

sqlite> select cos(pi()/4.0); 
---> 0.707106781186548 

Tôi không chắc chắn lý do tại sao thứ tự các tùy chọn để gcc quan trọng trong trường hợp cụ thể này, nhưng dường như nó d oes.

Tín dụng cho nhận thấy này đi vào Ludvick Lidicky 's bình luận về this blog post

+0

Bất kỳ ý tưởng làm thế nào để cài đặt này? Các tập tin chính nó không giúp đỡ nhiều. – jameshfisher

+0

@jameshfisher Hãy thử hỏi về nó trong một câu hỏi khác, đây là một khởi đầu. Trong tò mò, tôi đã cố gắng biên dịch các phần mở rộng tối nay. Thực hiện theo các hướng dẫn trong phần bình luận C ở đầu tệp là đủ đơn giản (bạn đã đọc tệp và tìm thấy tệp đó, đúng không?) Nhưng có một số lỗi. Nó biên dịch với gcc trên Ubuntu 14.04 LTS, với điều kiện tiên quyết "libsqlite3-dev", dẫn đến một lib "libsqlitefunctions.so" được chia sẻ. Cùng sqlite3 của Ubuntu cố gắng tải nó khi đưa ra lệnh SELECT load_extension ('./ libsqlitefunctions') nhưng ném một lỗi "undefined symbol: sinh". – Paul

+1

Đây là cách dễ dàng hơn để thiết lập hơn tôi mong đợi. Con đường để đi! –

0

SELECT AVG (x) trả về chỉ là năm của các giá trị ngày định dạng YYYY-MM-DD, vì vậy tôi tinh chỉnh giải pháp của CL chỉ hơi để thích ứng date:

SELECT DATE(JULIANDAY(MIN(MyDate)) + (JULIANDAY(MAX(MyDate)) - JULIANDAY(MIN(MyDate)))/2) as Median_Date 
FROM (
    SELECT MyDate 
     FROM MyTable 
     ORDER BY MyDate 
     LIMIT 2 - ((SELECT COUNT(*) FROM MyTable) % 2) -- odd 1, even 2 
     OFFSET (SELECT (COUNT(*) - 1)/2 FROM MyTable) 
); 
Các vấn đề liên quan