Trong MariaDB / MySQL:
SELECT AVG(dd.val) as median_val
FROM (
SELECT d.val, @rownum:[email protected]+1 as `row_number`, @total_rows:[email protected]
FROM data d, (SELECT @rownum:=0) r
WHERE d.val is NOT NULL
-- put some where clause here
ORDER BY d.val
) as dd
WHERE dd.row_number IN ( FLOOR((@total_rows+1)/2), FLOOR((@total_rows+2)/2) );
Steve Cohen chỉ ra rằng sau lần chuyển đầu tiên, @rownum sẽ chứa tổng số hàng. Điều này có thể được sử dụng để xác định giá trị trung bình, vì vậy không cần vượt qua hoặc tham gia lần thứ hai.
Ngoài ra AVG(dd.val)
và dd.row_number IN(...)
được sử dụng để tạo ra một trung vị chính xác khi có một số bản ghi chẵn. Lý luận:
SELECT FLOOR((3+1)/2),FLOOR((3+2)/2); -- when total_rows is 3, avg rows 2 and 2
SELECT FLOOR((4+1)/2),FLOOR((4+2)/2); -- when total_rows is 4, avg rows 2 and 3
Cuối cùng, MariaDB 10.3.3+ chứa hàm MEDIAN