日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

MYSQL 取中位数

發(fā)布時(shí)間:2025/7/14 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MYSQL 取中位数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是最簡(jiǎn)單的(希望不是太慢)的方式來(lái)計(jì)算與MySQL?我AVG(x)尋找,但我有一個(gè)很難找到計(jì)算現(xiàn)在一個(gè)簡(jiǎn)單的方法,我返回所有行到PHP,做一個(gè)排序,然后拿起中間行,但肯定要有簡(jiǎn)單的做它的方式一個(gè)MySQL查詢。 示例數(shù)據(jù):

id | val --------1 42 73 24 25 96 87 3

對(duì)排序val給2 2 3 4 7 8 9,所以應(yīng)該是4,SELECT AVG(val)這==5。
本文地址 :CodeGo.net/75717/?
-------------------------------------------------------------------------------------------------------------------------
1.?我只是發(fā)現(xiàn)了另一個(gè)答案網(wǎng)上在 在幾乎所有的SQL:

SELECT x.val from data x, data y GROUP BY x.val HAVING SUM(SIGN(1-SIGN(y.val-x.val))) = (COUNT(*)+1)/2

請(qǐng)確保您的列以及索引和索引的篩選和排序。驗(yàn)證與解釋計(jì)劃。

select count(*) from table --find the number of rows

計(jì)算“中位數(shù)”行數(shù)。median_row = floor(count / 2)。 然后挑選出來(lái)的名單:

select val from table order by val asc limit median_row,1

這應(yīng)該回報(bào)你與你想要的值一行。 雅各?
2.?與建議的解決方案(TheJacobTaylor)問(wèn)題是加入表格本身是慢如糖蜜為大型數(shù)據(jù)集。我建議的替代在mysql中運(yùn)行,已使用顯式的ORDER BY,這樣你就不必希望你的索引下令適當(dāng)給一個(gè)正確的結(jié)果,并且容易解開(kāi)的查詢來(lái)調(diào)試。

SELECT avg(t1.val) as median_val FROM ( SELECT @rownum:=@rownum+1 as `row_number`, d.valFROM data d, (SELECT @rownum:=0) rWHERE 1-- put some where clause hereORDER BY d.val ) as t1, (SELECT count(*) as total_rowsFROM data dWHERE 1-- put same where clause here ) as t2 WHERE 1 AND t1.row_number in ( floor((total_rows+1)/2), floor((total_rows+2)/2) );

[編輯] 添加AVG()周?chē)鷗1.val和ROW_NUMBER在(...)當(dāng)有偶數(shù)個(gè)記錄正確產(chǎn)生。推理:

SELECT floor((3+1)/2),floor((3+2)/2);#total_rows is 3, so avg row_numbers 2 and 2 SELECT floor((4+1)/2),floor((4+2)/2);#total_rows is 4, so avg row_numbers 2 and 3


3.?我發(fā)現(xiàn)接受的解決方案并沒(méi)有對(duì)我的MySQL安裝工作,返回一個(gè)空集,但這個(gè)查詢工作中,我測(cè)試了它在所有情況:

SELECT x.val from data x, data y GROUP BY x.val HAVING SUM(SIGN(1-SIGN(y.val-x.val)))/COUNT(*) > .5 LIMIT 1


4.?一此頁(yè)面上的MySQL有以下建議:

-- (mostly) High Performance scaling MEDIAN function per group -- Median defined in CodeGo.net -- -- by Peter Hlavac -- 06.11.2008 -- -- Example Table: DROP table if exists table_median; CREATE TABLE table_median (id INTEGER(11),val INTEGER(11)); COMMIT;INSERT INTO table_median (id, val) VALUES (1, 7), (1, 4), (1, 5), (1, 1), (1, 8), (1, 3), (1, 6), (2, 4), (3, 5), (3, 2), (4, 5), (4, 12), (4, 1), (4, 7); -- Calculating the MEDIAN SELECT @a := 0; SELECT id, AVG(val) AS MEDIAN FROM ( SELECT id, val FROM ( SELECT -- Create an index n for every id @a := (@a + 1) mod o.c AS shifted_n, IF(@a mod o.c=0, o.c, @a) AS n, o.id, o.val, -- the number of elements for every id o.c FROM ( SELECT t_o.id, val, c FROM table_median t_o INNER JOIN (SELECT id, COUNT(1) AS c FROM table_median GROUP BY id ) t2 ON (t2.id = t_o.id) ORDER BY t_o.id,val ) o ) a WHERE IF( -- if there is an even number of elements -- take the lower and the upper median -- and use AVG(lower,upper) c MOD 2 = 0, n = c DIV 2 OR n = (c DIV 2)+1, -- if its an odd number of elements -- take the first if its only one element -- or take the one in the middle IF( c = 1, n = 1, n = c DIV 2 + 1 ) ) ) a GROUP BY id; -- Explanation: -- The Statement creates a helper table like -- -- n id val count -- ---------------- -- 1, 1, 1, 7 -- 2, 1, 3, 7 -- 3, 1, 4, 7 -- 4, 1, 5, 7 -- 5, 1, 6, 7 -- 6, 1, 7, 7 -- 7, 1, 8, 7 -- -- 1, 2, 4, 1 -- 1, 3, 2, 2 -- 2, 3, 5, 2 -- -- 1, 4, 1, 4 -- 2, 4, 5, 4 -- 3, 4, 7, 4 -- 4, 4, 12, 4-- from there we can select the n-th element on the position: count div 2 + 1


5.?你函數(shù) CodeGo.net,在這里找到。?
6.?我提出了一個(gè)更快的方法。 獲取的行數(shù):SELECT CEIL(COUNT(*)/2) FROM data;然后取中間值在排序子查詢:SELECT max(val) FROM (SELECT val FROM data ORDER BY val limit @middlevalue) x;我測(cè)試了這個(gè)隨機(jī)數(shù)的5×10e6個(gè)數(shù)據(jù)集,它會(huì)發(fā)現(xiàn)在10秒以內(nèi)。?
7.?建立銷(xiāo)magic貼的回答,對(duì)于那些你不必做了,是通過(guò)另一個(gè)分組 選擇grp_field,t1.val FROM( 選擇grp_field,@ROWNUM:=IF(@S=grp_field,@ROWNUM +1,0)ASrow_number, @S:=IF(@S=grp_field,@S,grp_field)為二段,d.val 從數(shù)據(jù)D,(SELECT ROWNUM@:=0,@S:=0)R ORDER BY grp_field,d.val )為T(mén)1 JOIN( 選擇grp_field,COUNT(*)作為total_rows 從數(shù)據(jù)D GROUP BY grp_field )為T(mén)2 開(kāi)t1.grp_field=t2.grp_field WHERE t1.row_number=地板(total_rows / 2)+1;?
8.?不幸的是,TheJacobTaylor的也不是magic貼的答案返回準(zhǔn)確的結(jié)果為MySQL的最新版本。 從上面magic貼的答案是接近,但它不能正確計(jì)算結(jié)果集與偶數(shù)行。中值的定義為要么1)在偶數(shù)套的中間數(shù)的奇數(shù)編號(hào)的集合,或中間的兩個(gè)數(shù)的2)的平均值。 所以,這里的補(bǔ)丁來(lái)處理奇數(shù)和偶數(shù)設(shè)置magic貼的解決方案:

SELECT AVG(middle_values) AS 'median' FROM (SELECT t1.median_column AS 'middle_values' FROM(SELECT @row:=@row+1 as `row`, x.median_columnFROM median_table AS x, (SELECT @row:=0) AS rWHERE 1-- put some where clause hereORDER BY x.median_column) AS t1,(SELECT COUNT(*) as 'count'FROM median_table xWHERE 1-- put same where clause here) AS t2-- the following condition will return 1 record for odd number sets, or 2 records for even number sets.WHERE t1.row >= t2.count/2 and t1.row <= ((t2.count/2) +1)) AS t3;

為此,請(qǐng)按照下列3個(gè)簡(jiǎn)單步驟: 與您的表上面的代碼替換“median_table”(2出現(xiàn)) 替換“median_column”(出現(xiàn)3次)與你想找到的列 如果你有一個(gè)WHERE條件,將“WHERE 1”(事件2)與你的where條件?
9.?最上面的工作方案只為表的一個(gè)字段中,您可能需要獲得(第50百分位)上查詢多個(gè)領(lǐng)域。 這樣:

SELECT CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(field_name ORDER BY field_name SEPARATOR ','),',', 50/100 * COUNT(*) + 1), ',', -1) AS DECIMAL) AS `Median` FROM table_name;

您可以在例如替換“50”以上的任何百分位,是非常有效的。 只要確保你的GROUP_CONCAT,你可以改變它:

SET group_concat_max_len = 10485760; #10MB max length

更多詳細(xì)信息:?
10.?需要關(guān)心的奇數(shù)值計(jì)數(shù)-給出了在這種情況下,兩個(gè)中間值的平均值。

SELECT AVG(val) FROM( SELECT x.id, x.val from data x, data yGROUP BY x.id, x.valHAVING SUM(SIGN(1-SIGN(IF(y.val-x.val=0 AND x.id != y.id, SIGN(x.id-y.id), y.val-x.val)))) IN (ROUND((COUNT(*))/2), ROUND((COUNT(*)+1)/2))) sq


11.?兩個(gè)查詢方法: 優(yōu)先個(gè)獲得數(shù),最小值,最大值和平均值 第二個(gè)(與“LIMIT@數(shù)/ 2,1”和編制“ORDER BY ..”來(lái)獲得值 這些被包裹在一個(gè)函數(shù)defn,所以所有的值可以從一個(gè)調(diào)用中返回。 如果你的范圍是靜態(tài)的,你的數(shù)據(jù)不經(jīng)常變動(dòng),這可能是更有效的,而不是從頭開(kāi)始查詢這些值存儲(chǔ)的值每?
12.?答案很簡(jiǎn)單:得到以下指標(biāo)值:COUNT(*)/ 2取整。 答案:COUNT()/ 2調(diào)高或調(diào)低,這取決于你的高清或者你可以寫(xiě)一個(gè),如果為偶數(shù)的情況下和平均中間的數(shù)字(「該數(shù)()/ 2“四舍五入數(shù)字與”COUNT(*) / 2“四舍五入號(hào))。?
13.?如果MySQL有ROW_NUMBER,則中位數(shù)是(通過(guò)此SQL Server查詢得到啟發(fā)):

WITH Numbered AS ( SELECT *, COUNT(*) OVER () AS Cnt,ROW_NUMBER() OVER (ORDER BY val) AS RowNum FROM yourtable ) SELECT id, val FROM Numbered WHERE RowNum IN ((Cnt+1)/2, (Cnt+2)/2) ;

在該情況下,在你有偶數(shù)個(gè)條目。 如果你想每組找到,那么就PARTITION BY組中的OVER 搶?
14.?我的代碼,效率不表或額外的變量:

SELECT ((SUBSTRING_INDEX(SUBSTRING_INDEX(group_concat(val order by val), ',', floor(1+((count(val)-1) / 2))), ',', -1)) + (SUBSTRING_INDEX(SUBSTRING_INDEX(group_concat(val order by val), ',', ceiling(1+((count(val)-1) / 2))), ',', -1)))/2 as median FROM table;


15.?或者,你也可以在存儲(chǔ)這樣做

DROP PROCEDURE IF EXISTS median; DELIMITER // CREATE PROCEDURE median (table_name VARCHAR(255), column_name VARCHAR(255), where_clause VARCHAR(255)) BEGIN-- Set default parametersIF where_clause IS NULL OR where_clause = '' THENSET where_clause = 1;END IF;-- Prepare statementSET @sql = CONCAT("SELECT AVG(middle_values) AS 'median' FROM (SELECT t1.", column_name, " AS 'middle_values' FROM(SELECT @row:=@row+1 as `row`, x.", column_name, "FROM ", table_name," AS x, (SELECT @row:=0) AS rWHERE ", where_clause, " ORDER BY x.", column_name, ") AS t1,(SELECT COUNT(*) as 'count'FROM ", table_name, " xWHERE ", where_clause, ") AS t2-- the following condition will return 1 record for odd number sets, or 2 records for even number sets.WHERE t1.row >= t2.count/2AND t1.row <= ((t2.count/2)+1)) AS t3");-- Execute statementPREPARE stmt FROM @sql;EXECUTE stmt; END// DELIMITER ;-- Sample usage: -- median(table_name, column_name, where_condition); CALL median('products', 'price', NULL);

轉(zhuǎn)載于:https://www.cnblogs.com/07byte/p/5823654.html

總結(jié)

以上是生活随笔為你收集整理的MYSQL 取中位数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。