SQL - 计算中位数而不排序
SQL - Calculating median without sorting
我有一个包含一列整数值的 SQL table,我想找到这些值的中位数 而无需任何排序 。我首先尝试在 table 中找到大于和小于每个值的数字:
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
我不确定如何进行。我相信我想要上面 table 中的值,其中 greater_than
和 less_than
都等于 num_entries / 2
,但这只适用于 table偶数个条目。从我上面的内容中获得中位数的好方法是什么?
你可以这样做:
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
内部查询保证 return 1 或 2 个不同的非 null
值可能有许多 null
值。非 null
值可能会重复,但通过取最小值和最大值,可以使用这两个值来计算中位数。
注意:不要命名您的 table Values
:这是一个保留字。
寻找大于和小于等于 rows/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。
我有一个包含一列整数值的 SQL table,我想找到这些值的中位数 而无需任何排序 。我首先尝试在 table 中找到大于和小于每个值的数字:
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
我不确定如何进行。我相信我想要上面 table 中的值,其中 greater_than
和 less_than
都等于 num_entries / 2
,但这只适用于 table偶数个条目。从我上面的内容中获得中位数的好方法是什么?
你可以这样做:
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
内部查询保证 return 1 或 2 个不同的非 null
值可能有许多 null
值。非 null
值可能会重复,但通过取最小值和最大值,可以使用这两个值来计算中位数。
注意:不要命名您的 table Values
:这是一个保留字。
寻找大于和小于等于 rows/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。