我正在尝试用PL / SQL编写一个解析函数,当将其应用于表中的列时,该函数将为表中的每一行返回,该列的中位数不包括给定行。
要澄清的示例:假设我有一个表TABLE,该表由一个具有以下值的列X组成:
1
2
3
4
5
我想定义一个分析函数LOOM(),这样:
SELECT LOOM(X)
FROM TABLE
提供以下内容:
3.5
3.5
3
2.5
2.5
,即,对于每行,X的中位数,不包括给定的行。我一直在努力构建所需的LOOM()函数。
答案 0 :(得分:0)
我不确定是否有“聪明”的方法来做到这一点。您可以使用相关的子查询进行计算。
假设x
的值是唯一的-如您的示例中所示-
with t as (
select 1 as x from dual union all
select 2 as x from dual union all
select 3 as x from dual union all
select 4 as x from dual union all
select 5 as x from dual
)
select t.*,
(select median(x)
from t t2
where t2.x <> t.x
) as loom
from t;
编辑:
更有效的方法使用解析函数,但需要更直接地计算中位数。例如:
with t as (
select 1 as x from dual union all
select 2 as x from dual union all
select 3 as x from dual union all
select 4 as x from dual union all
select 5 as x from dual
)
select t.*,
(case when mod(cnt, 2) = 0
then (case when x <= candidate_1 then candidate_2 else candidate_1 end)
else (case when x <= candidate_1 then (candidate_2 + candidate_3)/2
when x = candidate_2 then (candidate_1 + candidate_3)/2
else (candidate_1 + candidate_2) / 2
end)
end) as loom
from (select t.*,
max(case when seqnum = floor(cnt / 2) then x end) over () as candidate_1,
max(case when seqnum = floor(cnt / 2) + 1 then x end) over () as candidate_2,
max(case when seqnum = floor(cnt / 2) + 2 then x end) over () as candidate_3
from (select t.*,
row_number() over (order by x) as seqnum,
count(*) over () as cnt
from t
) t
) t