Используя аналитику ratio_to_report - PullRequest
2 голосов
/ 11 марта 2011

Я пытаюсь получить процент строк, которые имеет набор определенного значения. Лучше всего объяснить на примере. Я могу сделать это по каждому столбцу очень просто, используя функцию «отношение к отчету» и over (), но у меня проблемы с несколькими группировками

Предположим, что таблица имеет 2 столбца:

column a         column b
1000             some data
1100             some data
2000             some data
1400             some data
1500             some data

С помощью следующего запроса я могу получить для этого набора доменов, каждый из которых составляет 20% от общего числа строк

select columna, count(*), trunc(ratio_to_report(count(columna)) over() * 100, 2) as perc
from table
group by columna
order by perc desc;

Однако мне нужно, например, определить процент и количество строк, содержащих 1000, 1400 или 2000; Посмотрев на него, вы можете определить его 60%, но для этого нужен запрос. Это должно быть эффективным, так как запрос будет выполняться для миллионов строк. Как я уже говорил ранее, я работаю над одним значением и его процентом, но это то, что меня бросает.

Похоже, мне нужно где-то поместить предложение IN, но значения не будут этими конкретными значениями каждый раз. Мне нужно будет получить значения для части «IN» из другой таблицы, если это имеет смысл. думаю, мне нужно несколько группировок.

Ответы [ 2 ]

1 голос
/ 11 марта 2011

Потенциально, вы ищете что-то вроде

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select 1000 a from dual
  3    union all
  4    select 1100 from dual
  5    union all
  6    select 1400 from dual
  7    union all
  8    select 1500 from dual
  9    union all
 10    select 2000 from dual
 11  )
 12  select (case when a in (1000,1400,1500)
 13               then 1
 14               else 0
 15           end) bucket,
 16         count(*),
 17         ratio_to_report(count(*)) over ()
 18    from x
 19   group by (case when a in (1000,1400,1500)
 20               then 1
 21               else 0
 22*          end)
SQL> /

    BUCKET   COUNT(*) RATIO_TO_REPORT(COUNT(*))OVER()
---------- ---------- -------------------------------
         1          3                              .6
         0          2                              .4
0 голосов
/ 12 марта 2011

Я не уверен, что полностью понимаю требование, но вам вообще нужно ratio_to_report? Посмотрите на следующее, и дайте мне знать, насколько это близко к тому, что вы хотите, и мы можем работать оттуда!

T1 - таблица, содержащая ваши данные выборки

create table t1(a primary key) as
   select 1000 as a from dual union all
   select 1100 as a from dual union all
   select 1400 as a from dual union all
   select 1500 as a from dual union all
   select 2000 as a from dual;

T2 - это упомянутая вами справочная таблица (где вы получаете список идентификаторов)

create table t2(a primary key) as
   select 1000 as a from dual union all
   select 1400 as a from dual union all
   select 2000 as a from dual;

Соединение слева от T1-> T2 вернет все строки в T1 в паре со всеми совпадающими строками в T2. Для каждого A в T1, который не существует в вашем наборе (T2), результат будет дополнен значением NULL. Мы можем использовать тот факт, что COUNT() не учитывает (хе-хе) нули.

select count(t1.a) as num_rows
      ,count(t2.a) as in_set
      ,count(t2.a) / count(t1.a) as shr_in_set
  from t1
  left 
  join t2 on(t1.a = t2.a);

Результат выполнения запроса:

  NUM_ROWS     IN_SET SHR_IN_SET
---------- ---------- ----------
         5          3         ,6
...