我有一个SQL表,其中包含一列整数值,我希望找到这些值的中位数而不进行任何排序。我首先尝试在表中找到大于和小于每个值的数字:
SELECT DISTINCT d1.v,
(SELECT COUNT(d2.v)
FROM Values d2
WHERE d2.v > d1.v
) AS greater_than,
(SELECT COUNT(d2.v)
FROM Values d2
WHERE d2.v < d1.v
) AS less_than
FROM Values d1
我不知道该怎么办。我相信我希望上表中greater_than
和less_than
都等于num_entries / 2
的值,但这只适用于具有偶数条目的表。从上面的内容中得到中位数的好方法是什么?
答案 0 :(得分:2)
你可以这样做:
SELECT (MIN(v)+MAX(v))/2
FROM (
SELECT CASE WHEN
LEAST((SELECT COUNT(*) FROM tbl WHERE v <= d1.v),
(SELECT COUNT(*) FROM tbl WHERE v >= d1.v))
>= (SELECT COUNT(*)/2 FROM tbl)
THEN v
END as v
FROM tbl d1
) as sub
内部查询保证在潜在的许多null
值中返回1或2个不同的非null
值。非null
值可能会重复,但通过取最小值和最大值,可以使用这两个值来计算中位数。
注意:不要为你的表Values
命名:这是一个保留字。
答案 1 :(得分:0)
查找大于和小于自身数的总数,该总数等于总行数/ 2。
create table med(id integer);
insert into med(id) values(1);
insert into med(id) values(2);
insert into med(id) values(3);
insert into med(id) values(4);
insert into med(id) values(5);
insert into med(id) values(6);
select (MIN(count)+MAX(count))/2 from
(select case when (select count(*) from
med A where A.id<B.id)=(select count(*)/2 from med) OR
(select count(*) from med A where A.id>B.id)=(select count(*)/2
from med) then cast(B.id as float)end as count from med B) C;
?column?
----------
3.5
(1 row)
你需要强制转换为浮动,否则你会得到3。