用于计算子组中的排名和中位数的 SQL 排名查询

标签 sql sqlite group-by ranking median

我想计算 Median此简单 xy_table子组y:

  x | y --groups--> gid |   x | y --medians-->  gid |   x | y
-------             -------------               -------------
0.1 | 4             0.0 | 0.1 | 4               0.0 | 0.1 | 4
0.2 | 3             0.0 | 0.2 | 3                   |     |
0.7 | 5             1.0 | 0.7 | 5               1.0 | 0.7 | 5
1.5 | 1             2.0 | 1.5 | 1                   |     |
1.9 | 6             2.0 | 1.9 | 6                   |     |
2.1 | 5             2.0 | 2.1 | 5               2.0 | 2.1 | 5
2.7 | 1             3.0 | 2.7 | 1               3.0 | 2.7 | 1

在此示例中,每个 x 都是唯一的,并且表格已按 x 排序。 我现在想要 GROUP BY round(x) 并获取每个组中包含 y 中位数的元组。

我已经可以用这个排名查询计算整个表的中位数:

SELECT a.x, a.y FROM xy_table a,xy_table b
WHERE a.y >= b.y
GROUP BY a.x, a.y
HAVING count(*) = (SELECT round((count(*)+1)/2) FROM xy_table)

输出:0.1, 4.0

但我还没有成功编写查询来计算子组的中位数。

注意:我没有可用的median() 聚合函数。也请不要提出具有特殊 PARTITIONRANKQUANTILE 语句的解决方案(如在类似但供应商特定的 SO questions 中找到的)。我需要纯 SQL(即与没有 median() 函数的 SQLite 兼容)

编辑:我实际上是在寻找 Medoid而不是 Median .

最佳答案

我建议用您的编程语言进行计算:

for each group:
  for each record_in_group:
    append y to array
  median of array

但如果你被 SQLite 困住了,你可以按 y 对每个组进行排序,然后像这样选择中间的记录 http://sqlfiddle.com/#!5/d4c68/55/0 :

更新:对于偶数 nr,只有更大的“中值”值才是重要的。行数,因此不需要 avg():

select groups.gid,
  ids.y median
from (
  -- get middle row number in each group (bigger number if even nr. of rows)
  -- note the integer divisions and modulo operator
  select round(x) gid,
    count(*) / 2 + 1 mid_row_right
  from xy_table
  group by round(x)
) groups
join (
  -- for each record get equivalent of
  -- row_number() over(partition by gid order by y)
  select round(a.x) gid,
    a.x,
    a.y,
    count(*) rownr_by_y
  from xy_table a
  left join xy_table b
    on round(a.x) = round (b.x)
    and a.y >= b.y
  group by a.x
) ids on ids.gid = groups.gid
where ids.rownr_by_y = groups.mid_row_right

关于用于计算子组中的排名和中位数的 SQL 排名查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15946580/

相关文章:

sql - 如何检查每个组中是否存在值(分组依据后)

mysql 使用 JOIN 将 2 个表插入到另一个表中

java - 如何从服务器检索值并将其保存在 sqlite 中并立即显示?

sql - elasticsearch - 总金额的总和大于使用聚合的某个金额

sql - 如何在 SQL 中进行渐进式递增每个 x 记录,其中每行的 x 可能不同?

mysql - MySQL 中何时使用单引号、双引号和反引号

python - 谷歌应用引擎 + 谷歌云存储 + Sqlite3 + Django/Python

php - 最简单的 jQuery、PHP、AJAX 和 sqlite 示例?

Pandas - 延长平均 session 时间

MySQL根据条件分别查询同一列的计数