mysql - 使用 GROUP BY 和 ORDER BY 优化计算中位数的查询

标签 mysql sql

请参阅下面我的 MySQL 表的示例部分:

表名称:eb_tickets

+-------------------+----------------------+
|  ticket_type      |  time_first_response |
|  Standard Traffic |  0:18:14             |
|  Standard Traffic |  0:48:06             |
|  Miscellaneous    |  44:12:23            |
|  Feed             |  4:48:22             | 
|  Miscellaneous    |  15:33:20            |
|  Banners          |  21:00:02            |
|  Integration      |  36:00:02            |
+-------------------+----------------------+

我想像这样输出响应,计算具有不同值 ASC 的中值:

+-------------------+----------------------+
|  median_group     |  median              | 
|  Banners          |  21:00:02            |
|  Feed             |  4:48:22             | 
|  Integration      |  36:00:02            |
|  Miscellaneous    |  32:36:13            |
|  Standard Traffic |  0:33:10             |
+-------------------+----------------------+

目前,我通过以下查询实现此目的:

SET @row_number:=0; 
SET @median_group:='';

SELECT 
    median_group, AVG(time_first_response) AS median
FROM
(SELECT 
    @row_number:=CASE
        WHEN @median_group = ticket_type THEN @row_number + 1
        ELSE 1
    END AS count_of_group,
    @median_group:=ticket_type AS median_group,
    ticket_type,
    time_first_response,
    (SELECT 
            COUNT(*)
        FROM
            eb_tickets
        WHERE
            a.ticket_type = ticket_type) AS total_of_group 
FROM
    (SELECT 
        ticket_type, time_first_response
    FROM
        eb_tickets           
    ORDER BY ticket_type, time_first_response) AS a) AS b
    WHERE
    count_of_group BETWEEN total_of_group / 2.0 AND total_of_group / 2.0 +1
    GROUP BY median_group

遗憾的是,此查询每条记录大约需要 1 秒,而且我正在查询数千条记录,ticket_type 列可能有 20 个不同的值。

是否可以优化我当前的查询以使查询执行得更快?

最佳答案

你可以这样尝试吗?

SELECT counter.ticket_type,AVG(time_first_response) AS median FROM
  (
    SELECT 
      IF(@type = type, @ctr := @ctr + 1, @ctr := 1) AS rownum, 
      @type := ticket_type AS ticket_type,
      time_first_response
    FROM eb_tickets
    ORDER BY ticket_type,time_first_response
  ) AS counter,
  (
    SELECT ticket_type, COUNT(*) AS rows
    FROM eb_tickets
    GROUP BY ticket_type
  ) AS types
  WHERE types.ticket_type = counter.ticket_type AND
    CASE rows % 2 
      WHEN 1 THEN rownum IN (ROUND(rows / 2),ROUND(rows / 2))
      ELSE rownum IN (ROUND(rows / 2),ROUND(rows / 2) + 1)
    END
  GROUP BY counter.ticket_type

最初,当我试验 SQL 时,我对列使用了较短的名称 - type 而不是 ticket_type 并且子查询 counter 是留下错误的列名 type 而不是 ticket_type

关于mysql - 使用 GROUP BY 和 ORDER BY 优化计算中位数的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51046294/

相关文章:

mysql - 6 节点 galera 集群冲突证书失败

sql - 如何获取最近 9 个月的数据?

java - 如何在JPA JPQL中编写这个SQL select?

mysql - 简单查询 - 为什么会抛出错误?

php - 通过 HTML 链接启动表单来更改 MySQL 数据?

c# - 如何根据我的数据库行以编程方式在 C# 中填充 WPF 网格?

c# - Entity Framework 如何使用带有谓词函数的 LINQ 检索行?

sql - 从 2 个 REF 列中获取两个日期之间的差异

sql - 在 SQL Hierarchy CTE 中显示所有子级和孙级

php - SQL查询从3个表中选择多对多