Sql Oracle如何为多列获取一列中最常见的值?
假设我有下表,如何按ID分组,并获得每列中最常见的值 p、 表很大,我需要对许多列执行此操作Sql Oracle如何为多列获取一列中最常见的值?,sql,oracle,Sql,Oracle,假设我有下表,如何按ID分组,并获得每列中最常见的值 p、 表很大,我需要对许多列执行此操作 ID Col1 Col2 Col3.... 1 A null 1 A X 1 B null 1 A Y 2 C X 2 C Y 2 A Y 3 B Z 3 A Z 3 A Z 3 B X 3 B Y 预期结果: ID Col1 Col2 Col3.
ID Col1 Col2 Col3....
1 A null
1 A X
1 B null
1 A Y
2 C X
2 C Y
2 A Y
3 B Z
3 A Z
3 A Z
3 B X
3 B Y
预期结果:
ID Col1 Col2 Col3....
1 A null
2 C Y
3 B Z
这里有一种方法,使用分析函数和
保持
:
select id,
min(col1) keep(dense_rank first order by cnt_col1 desc) as col1_mode,
min(col2) keep(dense_rank first order by cnt_col2 desc) as col2_mode,
min(col3) keep(dense_rank first order by cnt_col3 desc) as col3_mode
from (select id,
count(*) over (partition by id, col1) as cnt_col1,
count(*) over (partition by id, col2) as cnt_col2,
count(*) over (partition by id, col3) as cnt_col3
from t
) t
group by id;
在统计中,最常见的值称为“mode”,Oracle提供了一个函数来计算该值。因此,更简单的方法是使用stats\u mode()
:
编辑:
如注释中所述,stats\u mode()
不计算NULL
值。解决此问题的最简单方法是找到一些不在数据中的值,然后执行以下操作:
select id,
stats_mode(coalesce(col1, '<null>')) as mode_col1,
stats_mode(coalesce(col2, '<null>')) as mode_col2,
stats_mode(coalesce(col3, '<null>')) as mode_col3
from table t
group by id;
您好,Gordon,结果在
NULL
值上不符合要求。是否应该是stats\u mode(…)超过(按col1分区)
?@RenéNyffeneggerstats\u mode()
可以是聚合函数,也可以是分析函数。@ajmalmhd04。说得很好。在中编辑的备选方案。
select id,
stats_mode(coalesce(col1, '<null>')) as mode_col1,
stats_mode(coalesce(col2, '<null>')) as mode_col2,
stats_mode(coalesce(col3, '<null>')) as mode_col3
from table t
group by id;
select id,
(case when sum(case when col1 = mode_col1 then 1 else 0 end) >= sum(case when col1 is null then 1 else 0 end)
then mode_col1
else NULL
end) as mode_col1,
(case when sum(case when col2 = mode_col2 then 1 else 0 end) >= sum(case when col2 is null then 1 else 0 end)
then mode_col2
else NULL
end) as mode_col2,
(case when sum(case when col3 = mode_col13 then 1 else 0 end) >= sum(case when col3 is null then 1 else 0 end)
then mode_col3
else NULL
end) as mode_col3
from (select t.*,
stats_mode(col1) over (partition by id) as mode_col1,
stats_mode(col2) over (partition by id) as mode_col2,
stats_mode(col3) over (partition by id) as mode_col3
from table t
) t
group by id;