2017-02-02 3 views
0

я получил от запроса выберите этот вид таблицы (только простой пример):Как добавить столбец со специальными значениями и рассчитать процент?

D   C   Letter 
20153  200  x 
20154  300  x 
20161  250  x 
20162  180  x 
20153  500  y 
20154  380  y 
20161  550  y 
20162  170  y 
20153  230  z 
20154  700  z 
20161  210  z 
20162  185  z 

Таким образом, столбец D повторяется после четырех записей. C всегда отличается, и буква меняется после четырех записей. Всего, 20153 имеет 100 000, 20154 имеет 150 000, 20161 имеет 300 000 и 20162 имеет 250 000 записей. Я хотел бы поставить эти значения в соответствующих чисел, вычислить процент, так это выглядит следующим образом:

D   C   Letter Total  Perc 
20153  200  x   100.000 0.002 
20154  300  x   150.000 0.002 
20161  250  x   300.000 0.008 
20162  180  x   250.000 ... 
20153  500  y   100.000 ... 
20154  380  y   150.000 ... 
20161  550  y   300.000 ... 
20162  170  y   250.000 ... 
20153  230  z   100.000 ... 
20154  700  z   150.000 ... 
20161  210  z   300.000 ... 
20162  185  z   250.000 ... 

Как я могу это сделать? Предоставленные решения также могут быть записаны в R.

+5

SO не * писать код для меня * обслуживание. покажите свою попытку. –

+0

Пожалуйста, добавьте тег для базы данных (Oracle/PostgreSQL/SQL Server/MySQL и т. Д.) + Версия –

+0

Ну, я пробовал его с помощью cbind до конца моего df (1: nrow (df)), но почему-то это дает мне ошибку , Наверное, потому что у меня есть четыре разных значения вместо одного для всех. – victoria14

ответ

0

Вы должны определить где-то Ваши данные, например, в подзапросе V. Подзапрос X добавляет столбец RN со строками, разделенными letter и упорядоченными по D. Теперь мы можем join эти два запроса и сделать разделение:

with 
    v as (select 1 rn, 100000 as total from dual union all 
     select 2 rn, 150000 as total from dual union all 
     select 3 rn, 300000 as total from dual union all 
     select 4 rn, 250000 as total from dual), 
    x as (select t.*, row_number() over (partition by letter order by d) rn 
      from t) 
select rn, d, c, letter, total, cast(c/total as number(8, 5)) percent 
    from x join v using (rn) 
    order by letter, d 

тестовые данные и вывод:

create table t (d number(6), c number(6), letter varchar2(2)); 
insert into t values (20153, 200, 'x'); 
insert into t values (20154, 300, 'x'); 
insert into t values (20161, 250, 'x'); 
insert into t values (20162, 180, 'x'); 
insert into t values (20153, 500, 'y'); 
insert into t values (20154, 380, 'y'); 
insert into t values (20161, 550, 'y'); 
insert into t values (20162, 170, 'y'); 
insert into t values (20153, 230, 'z'); 
insert into t values (20154, 700, 'z'); 
insert into t values (20161, 210, 'z'); 
insert into t values (20162, 185, 'z'); 


    RN  D  C LETTER  TOTAL PERCENT 
----- ------- ------- ------ ---------- ---------- 
    1 20153  200 x   100000 0,00200 
    2 20154  300 x   150000 0,00200 
    3 20161  250 x   300000 0,00083 
    4 20162  180 x   250000 0,00072 
    1 20153  500 y   100000 0,00500 
    2 20154  380 y   150000 0,00253 
    3 20161  550 y   300000 0,00183 
    4 20162  170 y   250000 0,00068 
    1 20153  230 z   100000 0,00230 
    2 20154  700 z   150000 0,00467 
    3 20161  210 z   300000 0,00070 
    4 20162  185 z   250000 0,00074 
0

Это будет работать на некоторых базах данных

select  D,C,Letter 
      ,sum(C) over (partition by D)   as Total 
      ,C/sum(C) over (partition by D) * 100 as Perc 

from  mytable 

Если он не работает на вашей базе данных, то попробуйте следующий

select  t.D,t.C,t.Letter 
      ,s.Total 
      ,t.C/c.Total * 100 as Perc 

from  mytable t 

      join (select  D,sum(C) as Total 
        from  mytable 
        group by D 
       ) s 

      on s.D = t.D 
+0

Я уже пробовал это, но это дает мне неправильную сумму. Мой пример - это просто экстракт из моей таблицы, а это значит, что есть еще много строк. – victoria14

+0

Я уже исправил это сам. – victoria14

+0

Как ваш первый комментарий относится к этому решению? –