Oracle 中每列的最佳价值

Best Value per Each Column in Oracle

我有一个特殊的问题想要解决。假设我有一个具有以下结构和值的 table

Col1    Col2    Col3    Col4
A       3       S       #
A       3       S       #
A       3       X       #
A       3       X       #
A       3       X       @
A       3       X       @
A       5       X       @
A       5       X       @
A       5       S       #
A       5       S       #

如果我们在上面的 column2 中看到 3 的值重复了最大次数,col3 重复了 X 次最大次数而 Col4 有 #.

所以我想使用 SQL 形成一行输出,如下所示。

Col1    Col2    Col3    Col4
A       3       X       #

如果语句是SQL而不是PLSQL

就好了

看看这是否有帮助;示例数据来自第 1 - 14 行;您需要的查询从第 16 行开始。

SQL> with
  2  -- sample data
  3  test (col1, col2, col3, col4) as
  4    (select 'a', 3, 's', '#' from dual union all
  5     select 'a', 3, 's', '#' from dual union all
  6     select 'a', 3, 'x', '#' from dual union all
  7     select 'a', 3, 'x', '#' from dual union all
  8     select 'a', 3, 'x', '@' from dual union all
  9     select 'a', 3, 'x', '@' from dual union all
 10     select 'a', 5, 'x', '@' from dual union all
 11     select 'a', 5, 'x', '@' from dual union all
 12     select 'a', 5, 's', '#' from dual union all
 13     select 'a', 5, 's', '#' from dual
 14    )
 15  -- query you need
 16  select distinct
 17    t.col1,
 18    a.col2,
 19    b.col3,
 20    c.col4
 21  from test t cross join
 22    (select col2,
 23       rank() over (order by count(*) desc) rnk2
 24     from test
 25     group by col2
 26    ) a
 27    cross join
 28    (select col3,
 29       rank() over (order by count(*) desc) rnk3
 30     from test
 31     group by col3
 32    ) b
 33    cross join
 34    (select col4,
 35       rank() over (order by count(*) desc) rnk4
 36     from test
 37     group by col4
 38    ) c
 39  where a.rnk2 = 1
 40    and b.rnk3 = 1
 41    and c.rnk4 = 1
 42  /

C       COL2 C C
- ---------- - -
a          3 x #

SQL>

您可以使用下面的方法来获取需求

    with data as (select 'A' Col1,     3 Col2  ,      'S' Col3,      '#' Col4 from dual UNION all 
    select 'A' ,     3  ,     'S',       '#' from dual UNION all 
    select 'A' ,     3  ,     'X',       '#' from dual UNION all 
    select 'A'  ,    3  ,     'X',       '#' from dual UNION all 
    select 'A'  ,    3  ,     'X',      '@' from dual UNION all 
    select 'A'  ,    3  ,     'X',       '@' from dual UNION all 
    select 'A'  ,     5  ,     'X',       '@' from dual UNION all 
    select 'A'  ,    5   ,    'X',      '@' from dual UNION all 
    select 'A'  ,     5  ,     'S',       '#' from dual UNION all 
    select 'A'  ,    5   ,    'S',       '#' from dual),
    data1 as (
    select
    Col1,
    count(Col2) over (partition by col1,col2 order by col2) cnt_col2,
    Col2,
    count(Col3) over (partition by col1,col3 order by col3) cnt_col3,
    Col3,
    count(Col4) over (partition by col1,col4 order by col4) cnt_col4,
    Col4
    from data
    ),data2 as
    (
    select col1,col2,col3,col4,max(cnt_col2)||max(cnt_col3)||max(cnt_col4) Max_cnt
    from data1
    group by Col1,   Col2  ,   Col3,    Col4)
    select Col1,   Col2  ,   Col3,    Col4 from data2 
    where (max_cnt,col1) in (select max(max_cnt),
    col1 from data2 group by col1);

从 a_horse_with_no_name 的回答中获得帮助,您可以尝试以下是否可以解决您的性能问题

        SELECT DISTINCT d.*
    FROM   data d
    WHERE  ( col1, col2 ) IN (SELECT col1,
                                     Stats_mode(col2) col2
                              FROM   data
                              GROUP  BY col1)
           AND ( col1, col2, col3 ) IN (SELECT col1,
                                               col2,
                                               Stats_mode(col3) col3
                                        FROM   data
                                        GROUP  BY col1,
                                                  col2)
           AND ( col1, col2, col3, col4 ) IN (SELECT col1,
                                                     col2,
                                                     col3,
                                                     Stats_mode(col4) col4
                                              FROM   data
                                              GROUP  BY col1,
                                                        col2,
                                                        col3) 

您可以为此使用 stats_mode() 函数:

select STATS_MODE(col1) as col1,
       STATS_MODE(col2) as col2,
       STATS_MODE(col3) as col3,
       STATS_MODE(col4) as col4
from the_table
;

Online example