当前位置: 首页 > 面试题库 >

SQL查询中的四分位数

微生慈
2023-03-14
问题内容

我有一个非常简单的表,像这样:

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表示要从该行开始选择number
@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中,因此将它们连接起来,我们合并查询的结果,准备查询并执行它。



 类似资料:
  • 问题内容: 如何在按部分分组的查询中使用子查询? 我使用SQL Server 2008 R2和Delphi 2010 我收到此错误: 像这个查询: 按t1.sen分组 问题答案: 这是真实的方式

  • 本文向大家介绍SQL中的子查询,包括了SQL中的子查询的使用技巧和注意事项,需要的朋友参考一下 子查询是查询内的查询,即嵌套查询。它放置在查询中,其结果用于进一步评估外部查询。 在SQL中,子查询必须遵循一些规则。其中一些是- 子查询应放在括号内。 子查询可以与不同的运算符(如<,>,<=,> =,IN,BETWEEN等)一起使用。还可以使用SELECT,INSERT,DELETE,UPDATE等

  • 问题内容: 我的SQL查询可能有问题。在此查询中,我合并了4个不同的表。 我有一个用于存储常规信息的表(,)。 我有一个表,用于存储员工的一般信息(和)。 员工有工作。一名员工需要参加课程。这取决于他必须修的课程。此信息存储在表中(带有和)。 如果员工完成了课程,则将其存储在表中(带有和) 现在,我要搜索某个课程-当用户按下搜索按钮时,他应该得到两个不同的结果。 第一个:在这里您可以看到 哪个员工

  • 本文向大家介绍SQL数据分页查询的方法,包括了SQL数据分页查询的方法的使用技巧和注意事项,需要的朋友参考一下 最近学习了一下SQL的分页查询,总结了以下几种方法。 首先建立了一个表,随意插入的一些测试数据,表结构和数据如下图: 现在假设我们要做的是每页5条数据,而现在我们要取第三页的数据。(数据太少,就每页5条了) 方法一: 结果: 此方法是先取出前10条的SID(前两页),排除前10条数据的S

  • 问题内容: 我正在尝试按日期对我的讨论区中的帖子进行排序。这是我的代码: 这在语法上有什么问题吗?如果没有,还有什么可能是错误的?基本上发生的是结果没有显示出来。我删除了Order,它可以工作(但当然没有排序…) 问题答案: 订购应超出限制:

  • 问题内容: 有没有办法观察将由生成的SQL语句? 例如,我有这个:是否 可以查看其基础的原始SQL? 问题答案: 光滑2.X: 您可以按照Slick文档中所示打印查询语句: 对于其他类型的报表看,和。 光滑的3.X: 文件。