【问题标题】:How to create an aggregate function for median?如何为中位数创建聚合函数?
【发布时间】:2012-06-20 22:26:25
【问题描述】:

我需要在 Advantage-Database 中创建一个聚合函数来计算中值。

SELECT 
    group_field
  , MEDIAN(value_field) 
FROM 
  table_name
GROUP BY 
  group_field

似乎我找到的解决方案非常特定于所使用的 sql 引擎。

【问题讨论】:

    标签: sql math advantage-database-server median


    【解决方案1】:

    您可以在帮助文件中看到,ADS 中没有内置的中位数聚合函数:

    http://devzone.advantagedatabase.com/dz/webhelp/Advantage10.1/index.html

    恐怕你得自己写存储过程或者sql脚本来解决这个问题。

    以下问题的公认答案可能是您的解决方案: Simple way to calculate median with MySQL

    【讨论】:

      【解决方案2】:

      我已经用一个解决方案更新了这个答案,该解决方案避免加入,有利于将一些数据存储在 json 对象中。

      解决方案#1(两个选择和一个连接,一个获取计数,一个获取排名)

      这有点冗长,但确实有效,而且速度相当快。

      SELECT  x.group_field, 
              avg(
                  if( 
                      x.rank - y.vol/2 BETWEEN 0 AND 1, 
                      value_field, 
                      null
                  )
              ) as median
      FROM (
          SELECT  group_field, value_field, 
                  @r:= IF(@current=group_field, @r+1, 1) as rank, 
                  @current:=group_field
          FROM (
              SELECT group_field, value_field
              FROM table_name
              ORDER BY group_field, value_field
          ) z, (SELECT @r:=0, @current:='') v
      ) x, (
          SELECT group_field, count(*) as vol 
          FROM table_name
          GROUP BY group_field
      ) y WHERE x.group_field = y.group_field
      GROUP BY x.group_field
      

      解决方案 #2(使用 json 对象来存储计数并避免连接)

      SELECT group_field, 
          avg(
              if(
                  rank - json_extract(@vols, path)/2 BETWEEN 0 AND 1,
                  value_field,
                  null
              )
          ) as median
      FROM (
          SELECT group_field, value_field, path, 
              @rnk := if(@curr = group_field, @rnk+1, 1) as rank,
              @vols := json_set(
                  @vols, 
                  path, 
                  coalesce(json_extract(@vols, path), 0) + 1
              ) as vols,
              @curr := group_field
          FROM (
              SELECT p.group_field, p.value_field, concat('$.', p.group_field) as path
              FROM table_name
              JOIN (SELECT @curr:='', @rnk:=1, @vols:=json_object()) v
              ORDER BY group_field, value_field DESC
          ) z
      ) y GROUP BY group_field;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-09
        • 2011-12-01
        • 1970-01-01
        • 2012-09-06
        • 1970-01-01
        • 1970-01-01
        • 2021-06-30
        • 1970-01-01
        相关资源
        最近更新 更多