Наилучшее значение для каждого столбца в Oracle - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть особая проблема, которую я хочу решить. Предположим, скажем, у меня есть таблица с приведенной ниже структурой и значениями

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       #

Если в столбце 2 мы видим выше, значение 3 повторяется максимальное количество раз, col3 имеет X повторное максимальное количество раз, а Col4 имеет # .

Поэтому я хочу сформировать вывод строки, используя SQL, как показано ниже.

Col1    Col2    Col3    Col4
A       3       X       #

Было бы хорошо, если бы оператор был SQL, а не PL SQL

Ответы [ 3 ]

3 голосов
/ 17 апреля 2020

Для этого можно использовать функцию 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
;

Онлайн пример

1 голос
/ 17 апреля 2020

Вы можете использовать приведенное ниже, чтобы получить требование

    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) 
0 голосов
/ 17 апреля 2020

Посмотрите, поможет ли это; выборочные данные из строки № 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...