mysql – 在SQL查询中的四分位数
作者:互联网
我有一个非常简单的表:
CREATE TABLE IF NOT EXISTS LuxLog (
Sensor TINYINT,
Lux INT,
PRIMARY KEY(Sensor)
)
它包含来自不同传感器的数千个日志.
我希望所有传感器都有Q1和Q3.
我可以对每个数据进行一次查询,但对我来说最好对所有传感器进行一次查询(从一个查询中获取Q1和Q3)
我虽然这是一个相当简单的操作,因为四分位数被广泛使用并且是频率计算中的主要统计变量之一.事实是,我发现了大量过于复杂的解决方案,而我希望找到一些简洁明了的东西.
任何人都可以给我一个提示?
编辑:这是我在网上找到的一段代码,但它对我不起作用:
SELECT SUBSTRING_INDEX(
SUBSTRING_INDEX(
GROUP_CONCAT( -- 1) make a sorted list of values
Lux
ORDER BY Lux
SEPARATOR ','
)
, ',' -- 2) cut at the comma
, 75/100 * COUNT(*) -- at the position beyond the 90% portion
)
, ',' -- 3) cut at the comma
, -1 -- right after the desired list entry
) AS `75th Percentile`
FROM LuxLog
WHERE Sensor=12
AND Lux<>0
我得到1作为返回值,而它应该是一个可以除以10的数字(10,20,30 ….. 1000)
解决方法:
见SqlFiddle:http://sqlfiddle.com/#!9/accca6/2/6
注意:对于sqlfiddle,我生成了100行,每个介于1和100之间的整数都有一行,但它是一个随机顺序(在excel中完成).
这是代码:
SET @number_of_rows := (SELECT COUNT(*) FROM LuxLog);
SET @quartile := (ROUND(@number_of_rows*0.25));
SET @sql_q1 := (CONCAT('(SELECT "Q1" AS quartile_name , Lux, Sensor FROM LuxLog ORDER BY Lux DESC LIMIT 1 OFFSET ', @quartile,')'));
SET @sql_q3 := (CONCAT('( SELECT "Q3" AS quartile_name , Lux, Sensor FROM LuxLog ORDER BY Lux ASC LIMIT 1 OFFSET ', @quartile,');'));
SET @sql := (CONCAT(@sql_q1,' UNION ',@sql_q3));
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
编辑:
SET @current_sensor := 101;
SET @quartile := (ROUND((SELECT COUNT(*) FROM LuxLog WHERE Sensor = @current_sensor)*0.25));
SET @sql_q1 := (CONCAT('(SELECT "Q1" AS quartile_name , Lux, Sensor FROM LuxLog WHERE Sensor=', @current_sensor,' ORDER BY Lux DESC LIMIT 1 OFFSET ', @quartile,')'));
SET @sql_q3 := (CONCAT('( SELECT "Q3" AS quartile_name , Lux, Sensor FROM LuxLog WHERE Sensor=', @current_sensor,' ORDER BY Lux ASC LIMIT 1 OFFSET ', @quartile,');'));
SET @sql := (CONCAT(@sql_q1,' UNION ',@sql_q3));
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
基本推理如下:
对于四分位数1,我们希望从顶部获得25%,因此我们想知道有多少行,即:
SET @number_of_rows := (SELECT COUNT(*) FROM LuxLog);
现在我们知道了行数,我们想知道25%的行数,就是这一行:
SET @quartile := (ROUND(@number_of_rows*0.25));
然后找到一个四分位数,我们想要按Lux订购LuxLog表,然后得到行号“@quartile”,为了做到这一点,我们将OFFSET设置为@quartile,说我们要从行开始我们的选择编号@quartile,我们说限制1表示我们只想检索一行.那是 :
SET @sql_q1 := (CONCAT('(SELECT "Q1" AS quartile_name , Lux, Sensor FROM LuxLog ORDER BY Lux DESC LIMIT 1 OFFSET ', @quartile,')'));
我们(几乎)对其他四分位数(几乎)相同,但不是从顶部开始(从较高值到较低值),我们从底部开始(它解释了ASC).
但是现在我们只是将字符串存储在变量@ sql_q1和@sql_q3中,所以连接它们,我们联合查询的结果,我们准备查询并执行它.
标签:quantile,sql,mysql,percentile 来源: https://codeday.me/bug/20190824/1709425.html