2015-04-30 4 views
4

Рассмотрим следующий набор тестовых данных:Group By Заявление Proc SQL

data test; 
input Drug $ Quantity State $ Year; 
datalines; 
A 10 NY 2013 
A 20 NY 2014 
B 110 NY 2013 
B 210 NY 2014 
A 50 OH 2013 
A 60 OH 2014 
B 150 OH 2013 
B 260 OH 2014  
A 22 NY 2014 
B 100 OH 2013 
; 
RUN; 

Следующий код ниже суммирует количество препаратов A и B от наркотиков и государства за 2013 год:

proc sql; 
    create table testnew as 
    select *, sum(Quantity) as total from test 
    where Year=2013 
    group by Drug,State; 
    quit; 

Я заинтересован в том, чтобы получить долю каждого препарата в общем количестве для каждого штата. Так, например, в Огайо в 2013 году насчитывается в общей сложности 300 единиц наркотиков А и В. Доля А будет составлять 50/300, а доля В будет равна 250/300.

ниже код получает всего наркотики государства:

proc sql; 
    create table testnew1 as 
    select *, sum(Quantity) as total1 from test 
    where Year=2013 
    group by State; 
    quit; 

Я думал, что я мог бы объединить test и test1 и разделить total на total1, чтобы получить пропорции. Но есть ли более простой способ сделать это?

+1

Я бы рекомендовал использовать оконную функцию, если у вас есть те, которые доступны. Например, синтаксис стиля Oracle будет «SUM (количество) OVER (PARTITION BY state) AS state_total'. –

+1

@Mr.Функции окна Llama не поддерживаются в SAS Proc SQL – Reeza

ответ

1

Прежде всего, суммируя переменные в SQL, вы должны избегать включения входных переменных, отличных от «group by» vars и суммированных в итоговой таблице. Это для предотвращения дублирования строк.

Первый SQL-код, который вы написали, выводит 5 строк, даже если комбинация между лекарством/состоянием равна 4. Поэтому вместо выбора * лучше указать переменные группировки и использовать числовое обозначение в разделе «по группам»:

proc sql; 
    create table testnew as 
    select State, 
      Drug, 
      sum(Quantity) as total 
     from test 
     where Year=2013 
     group by 1, 2; 
quit; 

Чтобы пропорции каждого лекарственного средства по отношению к государству всего вы можете использовать подзапрос, где вы вычислить общее государством и не непосредственно использовать его во внешнем запросе:

proc sql; 
    create table testnew1 as 
    select State, 
      Drug, 
      sum(Quantity) as total, 
      total_by_state, 
      (calculated total)/total_by_state as proportion format=percent9.2 
     from (select *, 
        sum(Quantity) as total_by_state 
       from test 
       where Year=2013 
       group by State) 
     where Year=2013 
     group by 1, 2; 
quit; 

Если вы хотите, чтобы потом оставьте предложение where и включите переменную Year в группу как во внешнем, так и в внутреннем запросе.

+1

Почему бы избежать включения переменных, отличных от группы? Это одна из приятных функций SAS PROC SQL? – Reeza

+0

Как я уже сказал, если вы хотите обобщить некоторые переменные ** и **, вы не хотите дублировать строки (так как я думаю, что это результат, который Trevor хочет получить в этом случае) вы должны включить только группу by и суммированную вары. – DaBigNikoladze

0

Если вам нужно рассчитать итоговые значения без окна, вы потратите довольно много времени на запись SQL. В любом случае это вернет правильные результаты:

  1. В первом подзапросе я вычисляю итоги за каждый год/состояние/наркотик. Я делаю это, потому что у вас может быть один и тот же препарат на нескольких рядах.

  2. Во втором подзапроса общее для каждого года/государства

  3. Затем я присоединился к ним, чтобы вычислить процент

.

proc sql; 
    create table testnew1 as 
     select s1.Year, 
       s1.State, 
       s1.Drug, 
       sum(s1.total_by_drug) as Quantity, 
       sum(s2.total_by_state) , 
       sum(s1.total_by_drug)/sum(s2.total_by_state) as PCT_By_drug format=percent9.2 
      from ( /* Total by drug */ 
        select Year, 
         State, 
         Drug, 
         sum(Quantity) as total_by_drug 
        from test 
       group by Year, 
         State, 
         Drug 
       ) s1 
    inner join (/* Total by state */ 
        select Year, 
         State, 
         sum(Quantity) as total_by_state 
        from test 
       group by Year, 
         State 
       ) s2 
      on s1.State = s2.State 
      and s1.Year = s2.Year 
     where s1.Year = 2013 /* if you need to filter the year */ 
     group by s1. Year, 
       s1.State, 
       s1.Drug 
; 
run; 

Но если вы хотите дать выстрел SAS PROC ОТЧЕТА:

PROC REPORT DATA= test; 
    COLUMN State Drug Quantity,SUM pctDrugByState ; 
    DEFINE State/GROUP; 
    DEFINE Drug/GROUP; 
    DEFINE pctDrugByState/COMPUTED FORMAT=percent8.1 'Percent of State Total'; 
    * BREAK AFTER State/SUMMARIZE; * This shows total by State; 
    WHERE Year =2013; 

    compute before State; 
     totState = Quantity.sum; 
    endcomp; 

    compute pctDrugByState; 
     pctDrugByState = Quantity.sum/totState; 
    endcomp; 

RUN;