Сумма значений столбцов для нескольких групп в таблице Oracle - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть таблица со списком людей, пола, расы и их группы. Он имеет 2000 записей, разделенных на 8 групп. Я пытаюсь использовать PL / SQL, чтобы получить сумму людей по полу для каждой расы в каждой группе. Я подумал, что мне нужно, чтобы курсор заполнил переменную v_group 8-ю группами, а затем l oop для всех записей и получил количество для каждой. Каждый счет будет помещен в их собственную переменную, а затем вставлен новый суммированный счет и соответствующая группа в таблицу.

Вот пример того, что у меня есть.

OPEN cur_get_group;     
LOOP
    v_group := '';
    FETCH cur_get_group
       INTO v_group;
    EXIT WHEN cur_get_group%NOTFOUND;

    SELECT COUNT(*) INTO v_hisp_m FROM mytable WHERE sex = 'M' AND ethn_code = 'H';
    SELECT COUNT(*) INTO v_hisp_f FROM mytable WHERE sex = 'F' AND ethn_code = 'H';
    SELECT COUNT(*) INTO v_cauc_m FROM mytable WHERE sex = 'M' AND ethn_code = 'C';
    SELECT COUNT(*) INTO v_cauc_f FROM mytable WHERE sex = 'F' AND ethn_code = 'C';

    INSERT INTO mynewtable
    (group, hisp_m, hisp_f, cauc_m, cauc_f)
    VALUES
    (v_group, v_hisp_m, v_hisp_f, v_cauc_m, v_cauc_f);
    COMMIT;            

END LOOP;   

Я на правильном пути? Нужно ли делать l oop по-другому?

Ответы [ 2 ]

0 голосов
/ 08 апреля 2020

Реляционные базы данных работают на множестве условий сопоставления данных и очень хороши в этом. Они, однако, очень плохо обрабатывают единичные предметы. Научитесь думать, это условия наборов. Ваш процесс должен пройти таблицу исходных данных 5 раз (1 для процесса группы и подсчета). Хотя циклы иногда являются необходимым злом, они являются последним средством. Это можно сделать в 1 операторе, передавая источник 1 раз.

insert into mynewtable
     (group, hisp_m, hisp_f, cauc_m, cauc_f)

select group_code
     ,  sum(hisp_m)
     ,  sum(hisp_f)
     ,  sum(cauc_m)     
     ,  sum(cauc_f)  
  from    
       ( select group_code,
              , case when sex = 'F' AND ethn_code = 'H' then 1 else 0 end hisp_f
              , case when sex = 'M' AND ethn_code = 'H' then 1 else 0 end hisp_m
              , case when sex = 'F' AND ethn_code = 'C' then 1 else 0 end cauc_f              
              , case when sex = 'M' AND ethn_code = 'C' then 1 else 0 end cauc_m
           from youroldtable
        )
group by group_code; 

Кстати, НЕ используйте группу в качестве имени столбца. Это зарезервированное слово, и из-за этого очень трудно найти ошибки.

0 голосов
/ 08 апреля 2020

Похоже, вы хотите использовать pivot:

with rws as (
  select 'F' sex, 'H' eth from dual connect by level <= 3
  union all
  select 'F' sex, 'C' eth from dual connect by level <= 4
  union all
  select 'M' sex, 'H' eth from dual connect by level <= 2
  union all
  select 'M' sex, 'C' eth from dual
) 
  select * from rws
  pivot (
    count (*) for ( sex, eth ) in (
      ( 'F', 'H' ) fh,
      ( 'F', 'C' ) fc,
      ( 'M', 'H' ) mh,
      ( 'M', 'C' ) mc
    )
  );

FH    FC    MH    MC   
    3     4     2     1 

и вставить результат этого запроса в таблицу.

...